Skip to content

Commit 093bd87

Browse files
added benchmarks
1 parent 4a43d36 commit 093bd87

8 files changed

Lines changed: 477 additions & 1 deletion

File tree

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@ This lazy style of using the simdjson data structure could also be used with arr
8686
lua-simdjson will error out with any errors from simdjson encountered while parsing. They are very good at helping identify what has gone wrong during parsing.
8787

8888
## Benchmarks
89-
TODO: add some benchmarks
89+
I ran some benchmarks against lua-cjson, rapidjson, and dkjson. For each test, I loaded the JSON into memory, and then had the parsers go through each file 100 times and took the average time it took to parse. You can see all the results in the [benchmark](benchmark/) folder. I've included a sample output run via Lua (the LuaJIT graph looks very similar, also in the benchmark folder). The y-axis is logarithmic, so every half step down is twice as fast.
90+
91+
![Lua Performance Column Chart](benchmark/lua-perf.png)
92+
93+
9094

9195
## Caveats & Alternatives
9296
* there is no encoding/dumping a lua table to JSON (yet! Most other lua JSON libraries can handle this)

benchmark/bench.lua

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
local simdjson = require("simdjson")
2+
local cjson = require("cjson")
3+
local dkjson = require("dkjson")
4+
local rapidjson = require("rapidjson")
5+
local ftcsv = require("ftcsv")
6+
7+
local inspect = require("inspect")
8+
9+
-- load an entire file into memory
10+
local function loadFile(textFile)
11+
local file = io.open(textFile, "r")
12+
if not file then error("ftcsv: File not found at " .. textFile) end
13+
local lines = file:read("*all")
14+
file:close()
15+
return lines
16+
end
17+
18+
local csvfiles = {
19+
"twitter_api_response.json",
20+
"twitter_timeline.json",
21+
"numbers.json",
22+
"update-center.json",
23+
"mesh.json",
24+
"canada.json",
25+
"gsoc-2018.json",
26+
}
27+
28+
local function set(t)
29+
local newSet = {}
30+
for _, v in ipairs(t) do
31+
newSet[v] = true
32+
end
33+
return newSet
34+
end
35+
36+
local jsonchecker = {
37+
"apache_builds.json",
38+
"canada.json",
39+
"citm_catalog.json",
40+
"github_events.json",
41+
"google_maps_api_compact_response.json",
42+
"google_maps_api_response.json",
43+
"gsoc-2018.json",
44+
"instruments.json",
45+
"marine_ik.json",
46+
"mesh.json",
47+
"mesh.pretty.json",
48+
"numbers.json",
49+
"random.json",
50+
"repeat.json",
51+
"twitter_api_compact_response.json",
52+
"twitter_api_response.json",
53+
"twitterescaped.json",
54+
"twitter.json",
55+
"twitter_timeline.json",
56+
"update-center.json",
57+
"small/adversarial.json",
58+
"small/demo.json",
59+
"small/flatadversarial.json",
60+
"small/smalldemo.json",
61+
"small/truenull.json"
62+
}
63+
64+
local function sum(t)
65+
local totalTime = 0
66+
for _, time in ipairs(t) do
67+
totalTime = totalTime + time
68+
end
69+
return totalTime
70+
end
71+
72+
local function average(t)
73+
return sum(t) / #t
74+
end
75+
76+
local function timeIt(fn, contents)
77+
local times = {}
78+
local start, elapsed
79+
for i=1,100 do
80+
start = os.clock()
81+
fn(contents)
82+
elapsed = os.clock() - start
83+
table.insert(times, elapsed)
84+
end
85+
86+
return average(times)
87+
end
88+
89+
local totalTimes = {
90+
simdjson = 0,
91+
cjson = 0,
92+
dkjson = 0,
93+
rapidjson = 0
94+
}
95+
96+
97+
local csvFileSet = set(csvfiles)
98+
local outputCsv = {}
99+
for i,filename in ipairs(jsonchecker) do
100+
local row = {}
101+
local testFile = "jsonexamples/" .. filename
102+
local json_contents = loadFile(testFile)
103+
local time
104+
105+
print(testFile, "Bytes: " .. #json_contents)
106+
row["filename"] = filename
107+
108+
time = timeIt(simdjson.parse, json_contents)
109+
print("simd", time)
110+
row["simdjson"] = time
111+
totalTimes["simdjson"] = totalTimes["simdjson"] + time
112+
113+
time = timeIt(cjson.decode, json_contents)
114+
print("cjson", time)
115+
row["cjson"] = time
116+
totalTimes["cjson"] = totalTimes["cjson"] + time
117+
118+
time = timeIt(dkjson.decode, json_contents)
119+
print("dkjson", time)
120+
row["dkjson"] = time
121+
totalTimes["dkjson"] = totalTimes["dkjson"] + time
122+
123+
time = timeIt(rapidjson.decode, json_contents)
124+
print("rapidjson", time)
125+
row["rapidjson"] = time
126+
totalTimes["rapidjson"] = totalTimes["rapidjson"] + time
127+
128+
print("")
129+
130+
if csvFileSet[filename] then
131+
table.insert(outputCsv, row)
132+
end
133+
134+
end
135+
136+
local fileOutput = ftcsv.encode(outputCsv, ",")
137+
local file = assert(io.open("lua_test.csv", "w"))
138+
file:write(fileOutput)
139+
file:close()
140+
141+
print("Totals:")
142+
print(inspect(totalTimes))

benchmark/lua-perf.png

24.1 KB
Loading

benchmark/lua_results.csv

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"cjson","dkjson","filename","rapidjson","simdjson"
2+
"0.03332627","0.34340958","canada.json","0.02273244","0.01957085"
3+
"0.00902336","0.09975001","gsoc-2018.json","0.0094094700000005","0.0048763499999998"
4+
"0.0074011100000007","0.12183697","mesh.json","0.0034796200000008","0.0031762799999998"
5+
"0.0012705300000002","0.02003922","numbers.json","0.00044673999999958","0.00034920999999883"
6+
"8.9810000001194e-05","0.0011286799999991","twitter_api_response.json","8.5839999999564e-05","6.3079999999616e-05"
7+
"0.00032063000000051","0.0044230400000006","twitter_timeline.json","0.0003032900000008","0.00024571999999978"
8+
"0.0040162400000006","0.04850864","update-center.json","0.00420897","0.0032198200000013"

benchmark/lua_results_avg.txt

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
jsonexamples/apache_builds.json Bytes: 127275
2+
simd 0.00055886
3+
cjson 0.0006648
4+
dkjson 0.00971987
5+
rapidjson 0.00075601
6+
7+
jsonexamples/canada.json Bytes: 2251051
8+
simd 0.01957085
9+
cjson 0.03332627
10+
dkjson 0.34340958
11+
rapidjson 0.02273244
12+
13+
jsonexamples/citm_catalog.json Bytes: 1727204
14+
simd 0.0069842199999997
15+
cjson 0.0086915100000001
16+
dkjson 0.10970604
17+
rapidjson 0.00861807
18+
19+
jsonexamples/github_events.json Bytes: 65132
20+
simd 0.00024643000000026
21+
cjson 0.00031655000000043
22+
dkjson 0.0039641900000004
23+
rapidjson 0.00032308999999977
24+
25+
jsonexamples/google_maps_api_compact_response.json Bytes: 11812
26+
simd 0.00015186
27+
cjson 0.0001753199999991
28+
dkjson 0.00212726
29+
rapidjson 0.00016517999999955
30+
31+
jsonexamples/google_maps_api_response.json Bytes: 26102
32+
simd 0.00018610000000024
33+
cjson 0.00018462000000042
34+
dkjson 0.0023593100000001
35+
rapidjson 0.00017393999999982
36+
37+
jsonexamples/gsoc-2018.json Bytes: 3327831
38+
simd 0.0048763499999998
39+
cjson 0.00902336
40+
dkjson 0.09975001
41+
rapidjson 0.0094094700000005
42+
43+
jsonexamples/instruments.json Bytes: 220346
44+
simd 0.0010157800000003
45+
cjson 0.0013390100000004
46+
dkjson 0.02043801
47+
rapidjson 0.0012346699999998
48+
49+
jsonexamples/marine_ik.json Bytes: 2983466
50+
simd 0.024541229999999
51+
cjson 0.03997798
52+
dkjson 0.53947031
53+
rapidjson 0.02666556
54+
55+
jsonexamples/mesh.json Bytes: 723597
56+
simd 0.0031762799999998
57+
cjson 0.0074011100000007
58+
dkjson 0.12183697
59+
rapidjson 0.0034796200000008
60+
61+
jsonexamples/mesh.pretty.json Bytes: 1577353
62+
simd 0.0034339000000008
63+
cjson 0.0080027399999986
64+
dkjson 0.13587338
65+
rapidjson 0.0042685399999999
66+
67+
jsonexamples/numbers.json Bytes: 150124
68+
simd 0.00034920999999883
69+
cjson 0.0012705300000002
70+
dkjson 0.02003922
71+
rapidjson 0.00044673999999958
72+
73+
jsonexamples/random.json Bytes: 510476
74+
simd 0.0039299600000004
75+
cjson 0.0048504399999976
76+
dkjson 0.064787739999998
77+
rapidjson 0.0048125000000005
78+
79+
jsonexamples/repeat.json Bytes: 11356
80+
simd 4.6830000000284e-05
81+
cjson 6.976999999921e-05
82+
dkjson 0.00081937999999866
83+
rapidjson 5.9659999999155e-05
84+
85+
jsonexamples/twitter_api_compact_response.json Bytes: 10075
86+
simd 5.3140000000838e-05
87+
cjson 7.0550000000367e-05
88+
dkjson 0.00091499999999911
89+
rapidjson 6.8470000000502e-05
90+
91+
jsonexamples/twitter_api_response.json Bytes: 15253
92+
simd 6.3079999999616e-05
93+
cjson 8.9810000001194e-05
94+
dkjson 0.0011286799999991
95+
rapidjson 8.5839999999564e-05
96+
97+
jsonexamples/twitterescaped.json Bytes: 562408
98+
simd 0.0024212400000002
99+
cjson 0.0034035599999999
100+
dkjson 0.060517829999999
101+
rapidjson 0.0032888699999981
102+
103+
jsonexamples/twitter.json Bytes: 631515
104+
simd 0.0021985499999994
105+
cjson 0.0033034899999996
106+
dkjson 0.044229390000001
107+
rapidjson 0.0032022599999993
108+
109+
jsonexamples/twitter_timeline.json Bytes: 42233
110+
simd 0.00024571999999978
111+
cjson 0.00032063000000051
112+
dkjson 0.0044230400000006
113+
rapidjson 0.0003032900000008
114+
115+
jsonexamples/update-center.json Bytes: 533178
116+
simd 0.0032198200000013
117+
cjson 0.0040162400000006
118+
dkjson 0.04850864
119+
rapidjson 0.00420897
120+
121+
jsonexamples/small/adversarial.json Bytes: 80
122+
simd 2.2199999995109e-06
123+
cjson 1.6499999992448e-06
124+
dkjson 1.388999999989e-05
125+
rapidjson 2.2099999998204e-06
126+
127+
jsonexamples/small/demo.json Bytes: 387
128+
simd 2.8499999993414e-06
129+
cjson 3.0900000004408e-06
130+
dkjson 3.7309999999593e-05
131+
rapidjson 2.7500000004466e-06
132+
133+
jsonexamples/small/flatadversarial.json Bytes: 64
134+
simd 1.830000001064e-06
135+
cjson 1.6899999988595e-06
136+
dkjson 1.6239999999641e-05
137+
rapidjson 1.4199999995412e-06
138+
139+
jsonexamples/small/smalldemo.json Bytes: 204
140+
simd 2.6699999992275e-06
141+
cjson 2.8599999993162e-06
142+
dkjson 3.5780000000329e-05
143+
rapidjson 6.0800000002814e-06
144+
145+
jsonexamples/small/truenull.json Bytes: 12000
146+
simd 5.5900000000122e-05
147+
cjson 9.9980000001381e-05
148+
dkjson 0.0026005199999997
149+
rapidjson 4.2100000000005e-05
150+
151+
Totals:
152+
{
153+
cjson = 0.12660756,
154+
dkjson = 1.63672759,
155+
rapidjson = 0.094357749999998,
156+
simdjson = 0.07733488
157+
}

benchmark/luajit-perf.png

23.3 KB
Loading

benchmark/luajit_results.csv

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"cjson","dkjson","filename","rapidjson","simdjson"
2+
"0.02484794","0.11459856","canada.json","0.01377929","0.01340417"
3+
"0.0079303200000001","0.05620034","gsoc-2018.json","0.0085950099999999","0.0036615000000002"
4+
"0.0068585","0.03934749","mesh.json","0.0028935100000002","0.0030518899999998"
5+
"0.0012750300000002","0.0069491099999999","numbers.json","0.00042266999999995","0.00038534000000055"
6+
"6.9870000000236e-05","0.0004485200000002","twitter_api_response.json","6.8559999999849e-05","4.5070000000322e-05"
7+
"0.00025714000000008","0.0017159500000004","twitter_timeline.json","0.00024540999999942","0.00018965999999978"
8+
"0.0033273200000001","0.01943046","update-center.json","0.0035871300000004","0.0026317400000001"

0 commit comments

Comments
 (0)