Welcome to mirror list, hosted at ThFree Co, Russian Federation.

bench.lua « tests - github.com/mpx/lua-cjson.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 648020b19c99e52eb3307b3423b88fa20c553633 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env lua

-- This benchmark script measures wall clock time and should be
-- run on an unloaded system.
--
-- Your Mileage May Vary.
--
-- Mark Pulford <mark@kyne.com.au>

local json_module = os.getenv("JSON_MODULE") or "cjson"

require "socket"
local json = require(json_module)
local util = require "cjson.util"

local function find_func(mod, funcnames)
    for _, v in ipairs(funcnames) do
        if mod[v] then
            return mod[v]
        end
    end

    return nil
end

local json_encode = find_func(json, { "encode", "Encode", "to_string", "stringify", "json" })
local json_decode = find_func(json, { "decode", "Decode", "to_value", "parse" })

local function average(t)
    local total = 0
    for _, v in ipairs(t) do
        total = total + v
    end
    return total / #t
end

function benchmark(tests, seconds, rep)
    local function bench(func, iter)
        -- Use socket.gettime() to measure microsecond resolution
        -- wall clock time.
        local t = socket.gettime()
        for i = 1, iter do
            func(i)
        end
        t = socket.gettime() - t

        -- Don't trust any results when the run lasted for less than a
        -- millisecond - return nil.
        if t < 0.001 then
            return nil
        end

        return (iter / t)
    end

    -- Roughly calculate the number of interations required
    -- to obtain a particular time period.
    local function calc_iter(func, seconds)
        local iter = 1
        local rate
        -- Warm up the bench function first.
        func()
        while not rate do
            rate = bench(func, iter)
            iter = iter * 10
        end
        return math.ceil(seconds * rate)
    end

    local test_results = {}
    for name, func in pairs(tests) do
        -- k(number), v(string)
        -- k(string), v(function)
        -- k(number), v(function)
        if type(func) == "string" then
            name = func
            func = _G[name]
        end

        local iter = calc_iter(func, seconds)

        local result = {}
        for i = 1, rep do
            result[i] = bench(func, iter)
        end

        -- Remove the slowest half (round down) of the result set
        table.sort(result)
        for i = 1, math.floor(#result / 2) do
            table.remove(result, 1)
        end

        test_results[name] = average(result)
    end

    return test_results
end

function bench_file(filename)
    local data_json = util.file_load(filename)
    local data_obj = json_decode(data_json)

    local function test_encode()
        json_encode(data_obj)
    end
    local function test_decode()
        json_decode(data_json)
    end

    local tests = {}
    if json_encode then tests.encode = test_encode end
    if json_decode then tests.decode = test_decode end

    return benchmark(tests, 0.1, 5)
end

-- Optionally load any custom configuration required for this module
local success, data = pcall(util.file_load, ("bench-%s.lua"):format(json_module))
if success then
    util.run_script(data, _G)
    configure(json)
end

for i = 1, #arg do
    local results = bench_file(arg[i])
    for k, v in pairs(results) do
        print(("%s\t%s\t%d"):format(arg[i], k, v))
    end
end

-- vi:ai et sw=4 ts=4: