-
Notifications
You must be signed in to change notification settings - Fork 41
/
bench.lua
231 lines (152 loc) · 4.64 KB
/
bench.lua
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
if not ngx or not jit then
error('must run in resty-cli with LuaJIT')
end
--[[
local v = require "jit.v"
v.on("/tmp/dump.log")
--]]
-------------
-- Settings
-------------
local n_uuids = 1e6
local p_valid_uuids = 70
package.path = 'lib/?.lua;' .. package.path
local cuuid = require 'lua_uuid'
local lua_uuid = require 'uuid'
local ffi_uuid = require 'resty.uuid'
local luajit_uuid = require 'resty.jit-uuid'
package.loaded['resty.jit-uuid'] = nil
ngx.config.nginx_configure = function() return '' end
local luajit_uuid_no_pcre = require 'resty.jit-uuid'
math.randomseed(os.time())
---------------------
-- UUID v4 generation
---------------------
local tests = {
['C binding '] = cuuid,
['Pure Lua '] = lua_uuid.new,
['resty-jit-uuid'] = luajit_uuid.generate_v4,
['FFI binding '] = ffi_uuid.generate_random
}
local v4_results = {}
local time_reference
for k, uuid in pairs(tests) do
collectgarbage()
local tstart = os.clock()
for _ = 1, n_uuids do
uuid()
end
local time = os.clock() - tstart
v4_results[#v4_results+1] = {module = k, time = time}
if k == 'resty-jit-uuid' then
time_reference = time
end
end
for _, res in ipairs(v4_results) do
res.diff = ((res.time - time_reference)/time_reference)*100
end
table.sort(v4_results, function(a, b) return a.time < b.time end)
print(string.format('%s with %g UUIDs', jit.version, n_uuids))
print('UUID v4 (random) generation')
for i, result in ipairs(v4_results) do
print(string.format('%d. %s\ttook:\t%fs\t%+d%%', i, result.module,
result.time, result.diff))
end
---------------------
-- UUID v3 generation
---------------------
-- unique names, unique namespaces: no strings interned
local tests = {
['resty-jit-uuid'] = assert(luajit_uuid.factory_v3('cc7da0b0-0743-11e6-968a-bfd4d8c62f62'))
}
local names = {}
for i = 1, n_uuids do
names[i] = ffi_uuid.generate_random()
end
local v3_results = {}
for k, factory in pairs(tests) do
collectgarbage()
local tstart = os.clock()
for i = 1, n_uuids do
factory(names[i])
end
local time = os.clock() - tstart
v3_results[#v3_results+1] = {module = k, time = time}
end
table.sort(v3_results, function(a, b) return a.time < b.time end)
print('\nUUID v3 (name-based and MD5) generation if supported')
for i, result in ipairs(v3_results) do
print(string.format('%d. %s\ttook:\t%fs', i, result.module, result.time))
end
---------------------
-- UUID v5 generation
---------------------
-- unique names, unique namespaces: no strings interned
local tests = {
['resty-jit-uuid'] = assert(luajit_uuid.factory_v5('1b985f4a-06be-11e6-aff4-ff8d14e25128'))
}
local names = {}
for i = 1, n_uuids do
names[i] = ffi_uuid.generate_random()
end
local v5_results = {}
for k, factory in pairs(tests) do
collectgarbage()
local tstart = os.clock()
for i = 1, n_uuids do
factory(names[i])
end
local time = os.clock() - tstart
v5_results[#v5_results+1] = {module = k, time = time}
end
table.sort(v5_results, function(a, b) return a.time < b.time end)
print('\nUUID v5 (name-based and SHA-1) generation if supported')
for i, result in ipairs(v5_results) do
print(string.format('%d. %s\ttook:\t%fs', i, result.module, result.time))
end
-------------
-- Validation
-------------
local tests = {
['FFI binding '] = ffi_uuid.is_valid,
['resty-jit-uuid (JIT PCRE enabled)'] = luajit_uuid.is_valid,
['resty-jit-uuid (Lua patterns) '] = luajit_uuid_no_pcre.is_valid
}
local uuids = {}
local p_invalid_uuids = p_valid_uuids + (100 - p_valid_uuids) / 2
for i = 1, n_uuids do
local r = math.random(0, 100)
if r <= p_valid_uuids then
uuids[i] = ffi_uuid.generate_random()
elseif r <= p_invalid_uuids then
uuids[i] = '03111af4-f2ee-11e5-ba5e-43ddcc7efcdZ' -- invalid UUID
else
uuids[i] = '03111af4-f2ee-11e5-ba5e-43ddcc7efcd' -- invalid length
end
end
local valid_results = {}
for k, validate in pairs(tests) do
collectgarbage()
local check = {}
local tstart = os.clock()
for i = 1, n_uuids do
local ok = validate(uuids[i])
check[ok] = true
end
-- make sure there is no false positives here
if not check[true] or not check[false] then
error('all validations have the same result for '..k)
end
valid_results[#valid_results+1] = {
module = k,
time = os.clock() - tstart
}
end
table.sort(valid_results, function(a, b) return a.time < b.time end)
print(string.format('\nUUID validation if supported (set of %d%% valid, %d%% invalid)',
p_valid_uuids,
100 - p_valid_uuids))
for i, result in ipairs(valid_results) do
print(string.format('%d. %s\ttook:\t%fs', i,
result.module, result.time))
end