From 0b1ecf6684a534e2ed5aada96cd56f714bd320f5 Mon Sep 17 00:00:00 2001
From: Sergey Kaplun <skaplun@tarantool.org>
Date: Wed, 22 May 2024 15:24:36 +0300
Subject: [PATCH] perf: standardize uri_escape_unescape benchmark

Two new options are introduced:
* The `--output` option allows you to specify the output file.
* The `--output_format` option means the format for the printed output.
  The default is "console". It just prints the amount of iterations
  proceeded per second to the stdout. The "json" format contains all the
  information about the benchmark in a format similar to Google
  Benchmark's.

Usually, these options should be used together to dump machine-readable
results for the benchmarks.

NO_DOC=perf test
NO_CHANGELOG=perf test
NO_TEST=perf test
---
 perf/lua/uri_escape_unescape.lua | 56 ++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 14 deletions(-)

diff --git a/perf/lua/uri_escape_unescape.lua b/perf/lua/uri_escape_unescape.lua
index 04bb5dcf34..51ecbfd537 100644
--- a/perf/lua/uri_escape_unescape.lua
+++ b/perf/lua/uri_escape_unescape.lua
@@ -1,9 +1,16 @@
--- It is recommended to run benchmark using taskset for stable results.
--- taskset -c 1 tarantool uri_escape_unescape.lua
-
 local uri = require("uri")
 local clock = require("clock")
 local t = require("tarantool")
+local benchmark = require("benchmark")
+
+local USAGE = [[
+ This benchmark measures the performance of URI decoding and encoding
+ for the chunk with many symbols to be escaped.
+]]
+
+local params = benchmark.argparse(arg, {}, USAGE)
+
+local bench = benchmark.new(params)
 
 local _, _, build_type = string.match(t.build.target, "^(.+)-(.+)-(.+)$")
 if build_type == "Debug" then
@@ -29,18 +36,39 @@ local decode_sample = uri.escape(encode_sample, escape_opts)
 --     exit the parent trace.
 jit.opt.start("hotloop=1", "hotexit=1")
 
-local cycles = 10^3
-local start = clock.monotonic()
-for _ = 1, cycles do
-    uri.escape(encode_sample)
+local CYCLES = 10^3
+
+local tests = {{
+    name = "uri.escape",
+    payload = function()
+        for _ = 1, CYCLES do
+            uri.escape(encode_sample)
+        end
+    end,
+}, {
+    name = "uri.unescape",
+    payload = function()
+        for _ = 1, CYCLES do
+            uri.unescape(decode_sample)
+        end
+    end,
+}}
+
+local function run_test(testname, func)
+    local real_time = clock.time()
+    local cpu_time = clock.proc()
+    func()
+    local real_delta = clock.time() - real_time
+    local cpu_delta = clock.proc() - cpu_time
+    bench:add_result(testname, {
+        real_time = real_delta,
+        cpu_time = cpu_delta,
+        items = CYCLES,
+    })
 end
-local encode_time = cycles / (clock.monotonic() - start)
 
-start = clock.monotonic()
-for _ = 1, cycles do
-    uri.unescape(decode_sample)
+for _, test in ipairs(tests) do
+    run_test(test.name, test.payload)
 end
-local decode_time = cycles / (clock.monotonic() - start)
 
-print(("uri.escape   %.2f  runs/sec"):format(encode_time))
-print(("uri.unescape %.2f  runs/sec"):format(decode_time))
+bench:dump_results()
-- 
GitLab