Created
November 30, 2019 21:03
-
-
Save hnakamur/bb6f6dec5ea043417cc0b382a5a4cf76 to your computer and use it in GitHub Desktop.
OpenResty lua split benchmarkを自分でも試してみた
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## オリジナル | |
https://github.com/toritori0318/Dockerfiles/tree/b82cb44834e33f0777b42d5f9b799b230c3e3237/openresty-split-bench | |
http://toritori0318.hatenadiary.jp/entry/20191201/1575141320 | |
## 改変 | |
/lua/lua_split_f は私が追加しました。固定数でないと使えないので split と同列ではないのですが、参考として。 | |
## Run Server | |
``` | |
docker build -t local/openresty-split-bench . | |
docker run -it -p 89:80 local/openresty-split-bench | |
``` | |
## Benchmark | |
``` | |
# curl | |
curl 'http://localhost:89/lua/lua_split_a?c=10' | |
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM openresty/openresty:1.15.8.1-3-alpine-fat | |
ADD nginx.conf /usr/local/openresty/nginx/conf/nginx.conf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#daemon off; | |
worker_processes 1; | |
error_log /dev/stdout warn; | |
events { | |
worker_connections 1024; | |
} | |
pcre_jit on; | |
http { | |
init_by_lua_block { | |
function clock_time(title, block) | |
local st = os.clock() | |
block() | |
local ed = os.clock() | |
ngx.say(title .. ": " .. ed-st.. " sec") | |
end | |
} | |
server { | |
listen 80; | |
location / { | |
index index.html; | |
} | |
location /lua { | |
default_type text/html; | |
content_by_lua_block { | |
ngx.say("hello, lua") | |
} | |
} | |
location = /lua/ngx_re_split { | |
default_type text/html; | |
content_by_lua_block { | |
local ngx_re = require "ngx.re" | |
-- ngx_re.opt("jit_stack_size", 128 * 1024) | |
local params = ngx.req.get_uri_args() | |
local c = params["c"] or 1 | |
local d = "aaaaaaa,bbbbbbbbbbb,ccccccccccccc,ddddddddddddddd,eeeeeeeeeeeeee,f,ggggg,hhh,iii,jjjjjjj,k" | |
clock_time("ngx_re_split", function() | |
for i = 1, c do | |
local t, err = ngx_re.split(d, ",") | |
if err then | |
ngx.log(ngx.ERR, string.format("err: %s", err)) | |
else | |
-- ngx.log(ngx.WARN, string.format("t: %d", #t)) | |
end | |
end | |
end) | |
} | |
} | |
location = /lua/lua_split_a { | |
default_type text/html; | |
content_by_lua_block { | |
local function csplit(str,sep) | |
local ret={} | |
local n=1 | |
for w in str:gmatch("([^"..sep.."]*)") do | |
ret[n] = ret[n] or w -- only set once (so the blank after a string is ignored) | |
if w=="" then | |
n = n + 1 | |
end -- step forwards on a blank but not a string | |
end | |
return ret | |
end | |
local params = ngx.req.get_uri_args() | |
local c = params["c"] or 1 | |
local d = "aaaaaaa,bbbbbbbbbbb,ccccccccccccc,ddddddddddddddd,eeeeeeeeeeeeee,f,ggggg,hhh,iii,jjjjjjj,k" | |
clock_time("lua_split_a", function() | |
for i = 1, c do | |
local t = csplit(d, ",") | |
-- ngx.log(ngx.WARN, string.format("t: %d", #t)) | |
end | |
end) | |
} | |
} | |
location = /lua/lua_split_b { | |
default_type text/html; | |
content_by_lua_block { | |
local function gsplit(s,sep) | |
local i, done, g = 1, false, s:gmatch('(.-)'..sep..'()') | |
local function pass(...) | |
if ... == nil then | |
done = true | |
return s:sub(i) | |
end | |
i = select(select('#',...),...) | |
return ... | |
end | |
return function() | |
if done then | |
return | |
end | |
if s == '' or sep == '' then | |
done = true | |
return s | |
end | |
return pass(g()) | |
end | |
end | |
local params = ngx.req.get_uri_args() | |
local c = params["c"] or 1 | |
local d = "aaaaaaa,bbbbbbbbbbb,ccccccccccccc,ddddddddddddddd,eeeeeeeeeeeeee,f,ggggg,hhh,iii,jjjjjjj,k" | |
clock_time("lua_split_b", function() | |
for i = 1, c do | |
local t={} for c in gsplit(d, ",") do table.insert(t,c) end | |
-- ngx.log(ngx.WARN, string.format("t: %d", #t)) | |
end | |
end) | |
} | |
} | |
location = /lua/lua_split_c { | |
default_type text/html; | |
content_by_lua_block { | |
function string.gsplit(s, sep, plain) | |
local start = 1 | |
local done = false | |
local function pass(i, j, ...) | |
if i then | |
local seg = s:sub(start, i - 1) | |
start = j + 1 | |
return seg, ... | |
else | |
done = true | |
return s:sub(start) | |
end | |
end | |
return function() | |
if done then | |
return | |
end | |
if sep == '' then | |
done = true | |
return s | |
end | |
return pass(s:find(sep, start, plain)) | |
end | |
end | |
local params = ngx.req.get_uri_args() | |
local c = params["c"] or 1 | |
local d = "aaaaaaa,bbbbbbbbbbb,ccccccccccccc,ddddddddddddddd,eeeeeeeeeeeeee,f,ggggg,hhh,iii,jjjjjjj,k" | |
clock_time("lua_split_c", function() | |
for i = 1, c do | |
local t={} for c in d:gsplit(",") do table.insert(t,c) end | |
-- ngx.log(ngx.WARN, string.format("t: %d", #t)) | |
end | |
end) | |
} | |
} | |
location = /lua/lua_split_d { | |
default_type text/html; | |
content_by_lua_block { | |
local strfind = string.find | |
local strsub = string.sub | |
local tinsert = table.insert | |
local function strsplit(delimiter, text, plain) | |
plain = plain or false | |
local list = {} | |
local pos = 1 | |
if strfind("", delimiter, 1, plain) then -- this would result in endless loops | |
error("delimiter matches empty string!") | |
end | |
while 1 do | |
local first, last = strfind(text, delimiter, pos, plain) | |
if first then -- found? | |
tinsert(list, strsub(text, pos, first-1)) | |
pos = last+1 | |
else | |
tinsert(list, strsub(text, pos)) | |
break | |
end | |
end | |
return list | |
end | |
local params = ngx.req.get_uri_args() | |
local c = params["c"] or 1 | |
local d = "aaaaaaa,bbbbbbbbbbb,ccccccccccccc,ddddddddddddddd,eeeeeeeeeeeeee,f,ggggg,hhh,iii,jjjjjjj,k" | |
clock_time("lua_split_d", function() | |
for i = 1, c do | |
local t = strsplit(",", d) | |
-- ngx.log(ngx.WARN, string.format("t: %d", #t)) | |
end | |
end) | |
} | |
} | |
location = /lua/lua_split_e { | |
default_type text/html; | |
content_by_lua_block { | |
local function split(str, pat) | |
local t = {} -- NOTE: use {n = 0} in Lua-5.0 | |
local fpat = "(.-)" .. pat | |
local last_end = 1 | |
local s, e, cap = str:find(fpat, 1) | |
while s do | |
if s ~= 1 or cap ~= "" then | |
table.insert(t,cap) | |
end | |
last_end = e+1 | |
s, e, cap = str:find(fpat, last_end) | |
end | |
if last_end <= #str then | |
cap = str:sub(last_end) | |
table.insert(t, cap) | |
end | |
return t | |
end | |
local params = ngx.req.get_uri_args() | |
local c = params["c"] or 1 | |
local d = "aaaaaaa,bbbbbbbbbbb,ccccccccccccc,ddddddddddddddd,eeeeeeeeeeeeee,f,ggggg,hhh,iii,jjjjjjj,k" | |
clock_time("lua_split_e", function() | |
for i = 1, c do | |
local t = split(d, ",") | |
-- ngx.log(ngx.WARN, string.format("t: %d", #t)) | |
end | |
end) | |
} | |
} | |
location = /lua/lua_split_f { | |
default_type text/html; | |
content_by_lua_block { | |
local params = ngx.req.get_uri_args() | |
local c = params["c"] or 1 | |
local d = "aaaaaaa,bbbbbbbbbbb,ccccccccccccc,ddddddddddddddd,eeeeeeeeeeeeee,f,ggggg,hhh,iii,jjjjjjj,k" | |
clock_time("lua_split_e", function() | |
for i = 1, c do | |
local t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11 = string.match(d, '([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*)') | |
-- ngx.log(ngx.WARN, string.format("t11: %s", t11)) | |
end | |
end) | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ curl 'http://localhost:89/lua/lua_split_f?c=10' | |
lua_split_e: 0.000276 sec | |
$ curl 'http://localhost:89/lua/lua_split_f?c=10' | |
lua_split_e: 7.2e-05 sec | |
$ curl 'http://localhost:89/lua/ngx_re_split?c=10' | |
ngx_re_split: 0.000731 sec | |
$ curl 'http://localhost:89/lua/lua_split_a?c=10' | |
lua_split_a: 0.000443 sec | |
$ curl 'http://localhost:89/lua/lua_split_b?c=10' | |
lua_split_b: 0.000394 sec | |
$ curl 'http://localhost:89/lua/lua_split_c?c=10' | |
lua_split_c: 0.000434 sec | |
$ curl 'http://localhost:89/lua/lua_split_d?c=10' | |
lua_split_d: 0.00029 sec | |
$ curl 'http://localhost:89/lua/lua_split_e?c=10' | |
lua_split_e: 0.000162 sec | |
$ curl 'http://localhost:89/lua/lua_split_f?c=10' | |
lua_split_e: 5.4e-05 sec | |
$ curl 'http://localhost:89/lua/ngx_re_split?c=10' | |
ngx_re_split: 0.000418 sec | |
$ curl 'http://localhost:89/lua/lua_split_a?c=10' | |
lua_split_a: 0.000256 sec | |
$ curl 'http://localhost:89/lua/lua_split_b?c=10' | |
lua_split_b: 0.000174 sec | |
$ curl 'http://localhost:89/lua/lua_split_c?c=10' | |
lua_split_c: 0.000317 sec | |
$ curl 'http://localhost:89/lua/lua_split_e?c=10' | |
lua_split_e: 0.000196 sec | |
$ curl 'http://localhost:89/lua/lua_split_f?c=10' | |
lua_split_e: 4.3999999999999e-05 sec | |
$ curl 'http://localhost:89/lua/ngx_re_split?c=10000000' | |
ngx_re_split: 28.056177 sec | |
$ curl 'http://localhost:89/lua/lua_split_a?c=10000000' | |
lua_split_a: 41.272921 sec | |
$ curl 'http://localhost:89/lua/lua_split_b?c=10000000' | |
lua_split_b: 61.272173 sec | |
$ curl 'http://localhost:89/lua/lua_split_c?c=10000000' | |
lua_split_c: 19.150326 sec | |
$ curl 'http://localhost:89/lua/lua_split_d?c=10000000' | |
lua_split_d: 11.329389 sec | |
$ curl 'http://localhost:89/lua/lua_split_e?c=10000000' | |
lua_split_e: 40.524021 sec | |
$ curl 'http://localhost:89/lua/lua_split_f?c=10000000' | |
lua_split_e: 13.989293 sec | |
$ curl 'http://localhost:89/lua/lua_split_f?c=10000000' | |
lua_split_e: 14.0411 sec | |
$ curl 'http://localhost:89/lua/lua_split_f?c=10' | |
lua_split_e: 5.7999999995673e-05 sec | |
$ curl 'http://localhost:89/lua/lua_split_f?c=100' | |
lua_split_e: 0.00018199999999524 sec | |
$ curl 'http://localhost:89/lua/ngx_re_split?c=100' | |
ngx_re_split: 0.00036599999998543 sec | |
$ curl 'http://localhost:89/lua/lua_split_d?c=100' | |
lua_split_d: 0.00029900000001248 sec | |
$ curl 'http://localhost:89/lua/lua_split_a?c=100' | |
lua_split_a: 0.0012230000000102 sec | |
$ curl 'http://localhost:89/lua/lua_split_b?c=100' | |
lua_split_b: 0.00065299999999979 sec | |
$ curl 'http://localhost:89/lua/lua_split_c?c=100' | |
lua_split_c: 0.00089599999998313 sec | |
$ curl 'http://localhost:89/lua/lua_split_d?c=100' | |
lua_split_d: 0.00037800000001198 sec | |
$ curl 'http://localhost:89/lua/lua_split_e?c=100' | |
lua_split_e: 0.00061199999998962 sec | |
$ curl 'http://localhost:89/lua/lua_split_f?c=100' | |
lua_split_e: 0.00015500000000657 sec | |
$ curl 'http://localhost:89/lua/ngx_re_split?c=10000' | |
ngx_re_split: 0.035384999999991 sec | |
$ curl 'http://localhost:89/lua/lua_split_a?c=10000' | |
lua_split_a: 0.048181999999997 sec | |
$ curl 'http://localhost:89/lua/lua_split_b?c=10000' | |
lua_split_b: 0.069175999999999 sec | |
$ curl 'http://localhost:89/lua/lua_split_c?c=10000' | |
lua_split_c: 0.02699100000001 sec | |
$ curl 'http://localhost:89/lua/lua_split_d?c=10000' | |
lua_split_d: 0.020365999999996 sec | |
$ curl 'http://localhost:89/lua/lua_split_e?c=10000' | |
lua_split_e: 0.04945699999999 sec | |
$ curl 'http://localhost:89/lua/lua_split_f?c=10000' | |
lua_split_e: 0.022514999999999 sec | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
READMEにも書いてますがオリジナルは
http://toritori0318.hatenadiary.jp/entry/20191201/1575141320
です。
/lua/lua_split_f は私が追加しました。固定数でないと使えないので split と同列ではないのですが、参考として。
試してみてわかったのですが回数によって順位が変動するんですね。実行した順に関係するかもしれないので並び変えずそのままにしています。
私は Core i5 に換装した Express5800 で試しました。
string.match (/lua/lua_split_f) 方式は10回だと最速でしたが、10000000 回だと他のLua実装のほうが速いことがわかりました。