Skip to content

Commit 4a552c6

Browse files
committed
Initial implementation
Bench results: Lua5.3.3: (Lua5.1/5.2 have roughly the same numbers) $ lua bench.lua 10 testcases loaded: 0.000989637 run 10 validations: 3.8892e-05 $ lua bench.lua 100 testcases loaded: 0.001156522 run 100 validations: 0.000281029 $ lua bench.lua 1000 testcases loaded: 0.001209315 run 1000 validations: 0.00310095 $ lua bench.lua 10000 testcases loaded: 0.003009102 run 10000 validations: 0.024220092 $ lua bench.lua 100000 testcases loaded: 0.001657029 run 100000 validations: 0.219233237 $ lua bench.lua 1000000 testcases loaded: 0.001503246 run 1000000 validations: 2.234834785 $ lua bench.lua 10000000 testcases loaded: 0.001200452 run 10000000 validations: 21.634801401 LuaJIT 2.0.4: $ luajit bench.lua 10 testcases loaded: 0.00253848 run 10 validations: 0.000113092 $ luajit bench.lua 100 testcases loaded: 0.002582576 run 100 validations: 0.001147461 $ luajit bench.lua 1000 testcases loaded: 0.001086581 run 1000 validations: 0.003077144 $ luajit bench.lua 10000 testcases loaded: 0.001171133 run 10000 validations: 0.016859904 $ luajit bench.lua 100000 testcases loaded: 0.00256524 run 100000 validations: 0.109411399 $ luajit bench.lua 1000000 testcases loaded: 0.001154897 run 1000000 validations: 1.037945463 $ luajit bench.lua 10000000 testcases loaded: 0.000716779 run 10000000 validations: 10.114214835
0 parents  commit 4a552c6

7 files changed

+726
-0
lines changed

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "spec/JSON-Schema-Test-Suite"]
2+
path = spec/JSON-Schema-Test-Suite
3+
url = https://github.com/json-schema-org/JSON-Schema-Test-Suite.git

bench.lua

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
-- JSON schema validator benchmarking tool
2+
3+
local json = require 'cjson'
4+
local time = require 'posix.time'
5+
local jsonschema = require 'jsonschema'
6+
7+
local mrandom = math.random
8+
local clock_gettime = time.clock_gettime
9+
local CLOCK_PROCESS_CPUTIME_ID = time.CLOCK_PROCESS_CPUTIME_ID
10+
local function timer()
11+
local start = clock_gettime(CLOCK_PROCESS_CPUTIME_ID)
12+
return function()
13+
local cur = clock_gettime(CLOCK_PROCESS_CPUTIME_ID)
14+
return (cur.tv_sec + cur.tv_nsec/1e9) - (start.tv_sec + start.tv_nsec/1e9)
15+
end
16+
end
17+
18+
local blacklist = {
19+
-- edge cases, not supported features
20+
['object type matches objects'] = {
21+
['an array is not an object'] = true, -- empty object/array confusion
22+
},
23+
['array type matches arrays'] = {
24+
['an object is not an array'] = true, -- empty object/array confusion
25+
},
26+
['regexes are not anchored by default and are case sensitive'] = {
27+
['recognized members are accounted for'] = true, -- uses a unsupported pattern construct
28+
},
29+
['minLength validation'] = {
30+
['one supplementary Unicode code point is not long enough'] = true, -- unicode handling
31+
},
32+
['maxLength validation'] = {
33+
['two supplementary Unicode code points is long enough'] = true, -- unicode handling
34+
},
35+
}
36+
37+
local supported = {
38+
'spec/extra/sanity.json',
39+
'spec/extra/empty.json',
40+
'spec/JSON-Schema-Test-Suite/tests/draft4/type.json',
41+
-- objects
42+
'spec/JSON-Schema-Test-Suite/tests/draft4/properties.json',
43+
'spec/JSON-Schema-Test-Suite/tests/draft4/required.json',
44+
'spec/JSON-Schema-Test-Suite/tests/draft4/additionalProperties.json',
45+
'spec/JSON-Schema-Test-Suite/tests/draft4/patternProperties.json',
46+
'spec/JSON-Schema-Test-Suite/tests/draft4/minProperties.json',
47+
'spec/JSON-Schema-Test-Suite/tests/draft4/maxProperties.json',
48+
-- TODO: dependencies
49+
-- strings
50+
'spec/JSON-Schema-Test-Suite/tests/draft4/minLength.json',
51+
'spec/JSON-Schema-Test-Suite/tests/draft4/maxLength.json',
52+
'spec/JSON-Schema-Test-Suite/tests/draft4/pattern.json',
53+
-- numbers
54+
'spec/JSON-Schema-Test-Suite/tests/draft4/multipleOf.json',
55+
'spec/JSON-Schema-Test-Suite/tests/draft4/minimum.json',
56+
'spec/JSON-Schema-Test-Suite/tests/draft4/maximum.json',
57+
-- lists
58+
'spec/JSON-Schema-Test-Suite/tests/draft4/items.json',
59+
'spec/JSON-Schema-Test-Suite/tests/draft4/additionalItems.json',
60+
'spec/JSON-Schema-Test-Suite/tests/draft4/minItems.json',
61+
'spec/JSON-Schema-Test-Suite/tests/draft4/maxItems.json',
62+
--'spec/JSON-Schema-Test-Suite/tests/draft4/uniqueItems.json',
63+
-- misc
64+
-- 'spec/JSON-Schema-Test-Suite/tests/draft4/enum.json',
65+
}
66+
67+
local function decode_descriptor(path)
68+
local f = assert(io.open(path))
69+
local testsuite = json.decode(assert(f:read('*a')))
70+
f:close()
71+
return ipairs(testsuite)
72+
end
73+
74+
local NRUNS = assert(tonumber(arg[1]), 'run count required')
75+
76+
-- read all test cases
77+
local loadtimer = timer()
78+
local cases, ncases = {}, 0
79+
for _, descriptor in ipairs(supported) do
80+
for _, suite in decode_descriptor(descriptor) do
81+
local skipped = blacklist[suite.description] or {}
82+
if skipped ~= true then
83+
for _, case in ipairs(suite.tests) do
84+
ncases = ncases+1
85+
cases[ncases] = { jsonschema.generate_validator(suite.schema), case.data }
86+
end
87+
end
88+
end
89+
end
90+
print('testcases loaded:', loadtimer())
91+
92+
local runtimer = timer()
93+
for i=1, NRUNS do
94+
local case = cases[mrandom(ncases)]
95+
case[1](case[2])
96+
end
97+
print('run ' .. NRUNS .. ' validations:', runtimer())

0 commit comments

Comments
 (0)