diff --git a/bench.lua b/bench.lua index 315b8f3e979b50cd68f7bf8001a35f8adcca03aa..81691d953b16a4f2c0f2ebe41ad5048047b50db0 100644 --- a/bench.lua +++ b/bench.lua @@ -2,20 +2,28 @@ 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 +package.path = 'lib/?.lua;' .. package.path -local cuuid = require 'lua_uuid' -local lua_uuid = require 'uuid' -local ffi_uuid = require 'resty.uuid' +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()) @@ -23,6 +31,8 @@ math.randomseed(os.time()) --------------------- -- UUID v4 generation --------------------- + + local tests = { ['C binding '] = cuuid, ['Pure Lua '] = lua_uuid.new, @@ -30,8 +40,11 @@ local tests = { ['FFI binding '] = ffi_uuid.generate_random } + local v4_results = {} local time_reference + + for k, uuid in pairs(tests) do collectgarbage() @@ -47,37 +60,47 @@ for k, uuid in pairs(tests) do 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)) + 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 -tests = { +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() - local check = {} for i = 1, n_uuids do factory(names[i]) end @@ -86,32 +109,40 @@ for k, factory in pairs(tests) do 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 -tests = { +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() - local check = {} for i = 1, n_uuids do factory(names[i]) end @@ -120,56 +151,81 @@ for k, factory in pairs(tests) do 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 ------------- -tests = { + + +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 tstart = os.clock() + 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} + + 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)) + print(string.format('%d. %s\ttook:\t%fs', i, + result.module, result.time)) end diff --git a/lib/resty/jit-uuid.lua b/lib/resty/jit-uuid.lua index 240a8cdf089169afe846bdc70d362df7141333f6..e693cf3f3183662787eab518721c7bb07cad3804 100644 --- a/lib/resty/jit-uuid.lua +++ b/lib/resty/jit-uuid.lua @@ -149,7 +149,7 @@ do -- local u1 = uuid() ---> __call metamethod -- local u2 = uuid.generate_v4() function _M.generate_v4() - return fmt('%s%s%s%s-%s%s-%s%s-%s%s-%s%s%s%s%s%s', + return (fmt('%s%s%s%s-%s%s-%s%s-%s%s-%s%s%s%s%s%s', tohex(random(0, 255), 2), tohex(random(0, 255), 2), tohex(random(0, 255), 2), @@ -169,7 +169,7 @@ do tohex(random(0, 255), 2), tohex(random(0, 255), 2), tohex(random(0, 255), 2), - tohex(random(0, 255), 2)) + tohex(random(0, 255), 2))) end end @@ -282,13 +282,13 @@ do local hash, ver, var = hash_fn(concat(buf, ''), name) - return fmt('%s-%s-%s%s-%s%s-%s', sub(hash, 1, 8), + return (fmt('%s-%s-%s%s-%s%s-%s', sub(hash, 1, 8), sub(hash, 9, 12), ver, sub(hash, 15, 16), var, sub(hash, 19, 20), - sub(hash, 21, 32)) + sub(hash, 21, 32))) end end