From 52c9c398646772481656da4600ba83b6211d5bdd Mon Sep 17 00:00:00 2001 From: Yusheng Li Date: Tue, 26 Dec 2023 11:41:46 +0800 Subject: [PATCH] chore: add benchmark (#6) --- .luacheckrc | 1 + Makefile | 5 +- README.md | 72 ++++++++++++++++++++++++++- benchmark/complex-variable.lua | 34 +++++++++++++ benchmark/simple-variable-binding.lua | 34 +++++++++++++ benchmark/static-paths.lua | 31 ++++++++++++ benchmark/utils.lua | 6 ++- 7 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 benchmark/complex-variable.lua create mode 100644 benchmark/simple-variable-binding.lua create mode 100644 benchmark/static-paths.lua diff --git a/.luacheckrc b/.luacheckrc index ee0db7a..e1b26fa 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -1 +1,2 @@ unused_args = false +max_line_length = false diff --git a/Makefile b/Makefile index cbb2c56..cc36ddd 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,9 @@ test: busted spec/ bench: + RADIX_ROUTER_ROUTES=100000 RADIX_ROUTER_TIMES=10000000 luajit benchmark/static-paths.lua RADIX_ROUTER_ROUTES=100000 RADIX_ROUTER_TIMES=10000000 luajit benchmark/simple-variable.lua RADIX_ROUTER_ROUTES=100000 RADIX_ROUTER_TIMES=10000000 luajit benchmark/simple-prefix.lua - RADIX_ROUTER_TIMES=1000000 luajit benchmark/github-routes.lua \ No newline at end of file + RADIX_ROUTER_ROUTES=100000 RADIX_ROUTER_TIMES=1000000 luajit benchmark/complex-variable.lua + RADIX_ROUTER_ROUTES=100000 RADIX_ROUTER_TIMES=10000000 luajit benchmark/simple-variable-binding.lua + RADIX_ROUTER_TIMES=1000000 luajit benchmark/github-routes.lua diff --git a/README.md b/README.md index 93619d7..718c01c 100644 --- a/README.md +++ b/README.md @@ -104,5 +104,75 @@ local handler = router:match(path, ctx, params) ## 🚀 Benchmarks +Environments: -## License \ No newline at end of file +- Apple MacBook Pro(M1 Pro), 32GB +- LuaJIT 2.1.1700008891 + +``` +$ make bench + +RADIX_ROUTER_ROUTES=100000 RADIX_ROUTER_TIMES=10000000 luajit benchmark/static-paths.lua +========== static path ========== +routes : 100000 +times : 10000000 +elapsed : 0.120372 s +QPS : 83075798 +ns/op : 0.0120372 ns +path : /50000 +handler : 50000 + +RADIX_ROUTER_ROUTES=100000 RADIX_ROUTER_TIMES=10000000 luajit benchmark/simple-variable.lua +========== variable ========== +routes : 100000 +times : 10000000 +elapsed : 0.823292 s +QPS : 12146358 +ns/op : 0.0823292 ns +path : /1/foo +handler : 1 + +RADIX_ROUTER_ROUTES=100000 RADIX_ROUTER_TIMES=10000000 luajit benchmark/simple-prefix.lua +========== prefix ========== +routes : 100000 +times : 10000000 +elapsed : 0.726753 s +QPS : 13759833 +ns/op : 0.0726753 ns +path : /1/a +handler : 1 + +RADIX_ROUTER_ROUTES=100000 RADIX_ROUTER_TIMES=1000000 luajit benchmark/complex-variable.lua +========== variable ========== +routes : 100000 +times : 1000000 +elapsed : 0.922157 s +QPS : 1084414 +ns/op : 0.922157 ns +path : /aa/bb/cc/dd/ee/ff/gg/hh/ii/jj/kk/ll/mm/nn/oo/pp/qq/rr/ss/tt/uu/vv/ww/xx/yy/zz50000 +handler : 50000 + +RADIX_ROUTER_ROUTES=100000 RADIX_ROUTER_TIMES=10000000 luajit benchmark/simple-variable-binding.lua +========== variable ========== +routes : 100000 +times : 10000000 +elapsed : 2.183163 s +QPS : 4580510 +ns/op : 0.2183163 ns +path : /1/foo +handler : 1 +params : name = foo + +RADIX_ROUTER_TIMES=1000000 luajit benchmark/github-routes.lua +========== github apis ========== +routes : 609 +times : 1000000 +elapsed : 0.384233 s +QPS : 2602587 +ns/op : 0.384233 ns +path : /repos/vm-001/lua-radix-router/import +handler : /repos/{owner}/{repo}/import + +``` + +## License diff --git a/benchmark/complex-variable.lua b/benchmark/complex-variable.lua new file mode 100644 index 0000000..35d959f --- /dev/null +++ b/benchmark/complex-variable.lua @@ -0,0 +1,34 @@ +local Router = require "radix-router" +local utils = require "benchmark.utils" + +local route_n = os.getenv("RADIX_ROUTER_ROUTES") or 1000 * 100 +local times = os.getenv("RADIX_ROUTER_TIMES") or 1000 * 1000 * 10 + +local router +do + local routes = {} + for i = 1, route_n do + routes[i] = { + paths = { + string.format("/aa/{bb}/cc/{dd}/ee/{ff}/gg/{hh}/ii/{jj}/kk/{ll}/mm/{nn}/oo/{pp}/qq/{rr}/ss/{tt}/uu/{vv}/ww/{xx}/yy/zz%d", i) + }, handler = i } + end + router = Router.new(routes) +end + +local path = "/aa/bb/cc/dd/ee/ff/gg/hh/ii/jj/kk/ll/mm/nn/oo/pp/qq/rr/ss/tt/uu/vv/ww/xx/yy/zz" .. route_n / 2 + +local elapsed = utils.timing(function() + for _ = 1, times do + router:match(path) + end +end) + +utils.print_result({ + title = "variable", + routes = route_n, + times = times, + elapsed = elapsed, + benchmark_path = path, + benchmark_handler = router:match(path), +}) diff --git a/benchmark/simple-variable-binding.lua b/benchmark/simple-variable-binding.lua new file mode 100644 index 0000000..3be77c6 --- /dev/null +++ b/benchmark/simple-variable-binding.lua @@ -0,0 +1,34 @@ +local Router = require "radix-router" +local utils = require "benchmark.utils" + +local route_n = os.getenv("RADIX_ROUTER_ROUTES") or 1000 * 100 +local times = os.getenv("RADIX_ROUTER_TIMES") or 1000 * 1000 * 10 + +local router +do + local routes = {} + for i = 1, route_n do + routes[i] = { paths = { string.format("/%d/{name}", i) }, handler = i } + end + router = Router.new(routes) +end + +local path = "/1/foo" +local params = {} + +local elapsed = utils.timing(function() + for _ = 1, times do + router:match(path, nil, params) + end +end) + +utils.print_result({ + title = "variable", + routes = route_n, + times = times, + elapsed = elapsed, + benchmark_path = path, + benchmark_handler = router:match(path), +}, { + { name = "params", value = string.format("name = " .. params.name) } +}) diff --git a/benchmark/static-paths.lua b/benchmark/static-paths.lua new file mode 100644 index 0000000..ecdf49f --- /dev/null +++ b/benchmark/static-paths.lua @@ -0,0 +1,31 @@ +local Router = require "radix-router" +local utils = require "benchmark.utils" + +local route_n = os.getenv("RADIX_ROUTER_ROUTES") or 1000 * 100 +local times = os.getenv("RADIX_ROUTER_TIMES") or 1000 * 1000 * 10 + +local router +do + local routes = {} + for i = 1, route_n do + routes[i] = { paths = { string.format("/%d", i) }, handler = i } + end + router = Router.new(routes) +end + +local path = "/" .. route_n / 2 + +local elapsed = utils.timing(function() + for _ = 1, times do + router:match(path) + end +end) + +utils.print_result({ + title = "static path", + routes = route_n, + times = times, + elapsed = elapsed, + benchmark_path = path, + benchmark_handler = router:match(path), +}) diff --git a/benchmark/utils.lua b/benchmark/utils.lua index 68d94ff..da54cbb 100644 --- a/benchmark/utils.lua +++ b/benchmark/utils.lua @@ -1,11 +1,12 @@ local fmt = string.format + local function timing(fn) local start_time = os.clock() fn() return os.clock() - start_time end -local function print_result(result) +local function print_result(result, items) print(fmt("========== %s ==========", result.title)) print("routes :", result.routes) print("times :", result.times) @@ -14,6 +15,9 @@ local function print_result(result) print("ns/op :", result.elapsed * 1000 * 1000 / result.times .. " ns") print("path :", result.benchmark_path) print("handler :", result.benchmark_handler) + for _, item in ipairs(items or {}) do + print(fmt("%s : %s", item.name, item.value)) + end print() end