aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMark Pulford <mark@kyne.com.au>2012-01-13 22:11:17 +1030
committerMark Pulford <mark@kyne.com.au>2012-03-04 18:54:34 +1030
commit46ba498b003b1ac4898b8db39c9aea5158af093f (patch)
tree369648eb4b2eaf3322719ac1dc9db7d091ca4581 /tests
parent3eee7e3db0ef209427f26be3099a0033deb86cb7 (diff)
downloadlua-cjson-46ba498b003b1ac4898b8db39c9aea5158af093f.tar.gz
lua-cjson-46ba498b003b1ac4898b8db39c9aea5158af093f.tar.bz2
lua-cjson-46ba498b003b1ac4898b8db39c9aea5158af093f.zip
Improve benchmark stability
Update benchmark script to average the best half (round up) of the result set. Ensure the initial call rate is calculated from a run of at least 1ms. Remove garbage collection control since any variations due to garbage collection are better handled by averaging multiple results.
Diffstat (limited to 'tests')
-rwxr-xr-xtests/bench.lua43
1 files changed, 36 insertions, 7 deletions
diff --git a/tests/bench.lua b/tests/bench.lua
index 0299ff2..cae4902 100755
--- a/tests/bench.lua
+++ b/tests/bench.lua
@@ -1,6 +1,7 @@
1#!/usr/bin/env lua 1#!/usr/bin/env lua
2 2
3-- Simple JSON benchmark. 3-- This benchmark script measures wall clock time and should be
4-- run on an unloaded system.
4-- 5--
5-- Your Mileage May Vary. 6-- Your Mileage May Vary.
6-- 7--
@@ -25,24 +26,44 @@ end
25local json_encode = find_func(json, { "encode", "Encode", "to_string", "stringify", "json" }) 26local json_encode = find_func(json, { "encode", "Encode", "to_string", "stringify", "json" })
26local json_decode = find_func(json, { "decode", "Decode", "to_value", "parse" }) 27local json_decode = find_func(json, { "decode", "Decode", "to_value", "parse" })
27 28
29local function average(t)
30 local total = 0
31 for _, v in ipairs(t) do
32 total = total + v
33 end
34 return total / #t
35end
36
28function benchmark(tests, seconds, rep) 37function benchmark(tests, seconds, rep)
29 local function bench(func, iter) 38 local function bench(func, iter)
30 -- collectgarbage("stop") 39 -- Use socket.gettime() to measure microsecond resolution
31 collectgarbage("collect") 40 -- wall clock time.
32 local t = socket.gettime() 41 local t = socket.gettime()
33 for i = 1, iter do 42 for i = 1, iter do
34 func(i) 43 func(i)
35 end 44 end
36 t = socket.gettime() - t 45 t = socket.gettime() - t
37 -- collectgarbage("restart") 46
47 -- Don't trust any results when the run lasted for less than a
48 -- millisecond - return nil.
49 if t < 0.001 then
50 return nil
51 end
52
38 return (iter / t) 53 return (iter / t)
39 end 54 end
40 55
41 -- Roughly calculate the number of interations required 56 -- Roughly calculate the number of interations required
42 -- to obtain a particular time period. 57 -- to obtain a particular time period.
43 local function calc_iter(func, seconds) 58 local function calc_iter(func, seconds)
44 local base_iter = 10 59 local iter = 1
45 local rate = (bench(func, base_iter) + bench(func, base_iter)) / 2 60 local rate
61 -- Warm up the bench function first.
62 func()
63 while not rate do
64 rate = bench(func, iter)
65 iter = iter * 10
66 end
46 return math.ceil(seconds * rate) 67 return math.ceil(seconds * rate)
47 end 68 end
48 69
@@ -55,13 +76,21 @@ function benchmark(tests, seconds, rep)
55 name = func 76 name = func
56 func = _G[name] 77 func = _G[name]
57 end 78 end
79
58 local iter = calc_iter(func, seconds) 80 local iter = calc_iter(func, seconds)
81
59 local result = {} 82 local result = {}
60 for i = 1, rep do 83 for i = 1, rep do
61 result[i] = bench(func, iter) 84 result[i] = bench(func, iter)
62 end 85 end
86
87 -- Remove the slowest half (round down) of the result set
63 table.sort(result) 88 table.sort(result)
64 test_results[name] = result[rep] 89 for i = 1, math.floor(#result / 2) do
90 table.remove(result, 1)
91 end
92
93 test_results[name] = average(result)
65 end 94 end
66 95
67 return test_results 96 return test_results