Last active
June 17, 2018 16:28
-
-
Save meepen/90dba4c510c8721e3b82014abeaea3f7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- major features of the hook library need to be considered | |
-- performance is eaten from in-engine hook.Call calls every few frames/ticks | |
-- add/remove are not super important but should be considered still | |
local hook_name = "HookSuite" | |
local slow = true | |
local call_count = slow and 32000000 or 2000000000 | |
local no_hook_call_count = slow and 200000000 or 2000000000 | |
local invalid_call_count = slow and 200 or 20000 | |
local hooks = { | |
function() | |
end, | |
function() | |
end, | |
function() | |
end | |
} | |
local gm = { | |
[hook_name] = function() end, | |
NEVERUSETHISOK = function() end | |
} | |
return { | |
CallNoGM = function(lib) | |
local call = lib.Call | |
for i = 1, call_count do | |
call(hook_name) | |
end | |
return call_count | |
end, | |
CallGM = function(lib) | |
local call = lib.Call | |
for i = 1, call_count do | |
call(hook_name, gm) | |
end | |
return call_count | |
end, | |
CallNoHooks = function(lib) | |
local call = lib.Call | |
local hook_name, no_hook_call_count = "NEVERUSETHISOK", no_hook_call_count -- yes this is important | |
for i = 1, no_hook_call_count do | |
call(hook_name) | |
end | |
return no_hook_call_count | |
end, | |
CallGMOnly = function(lib) | |
local call = lib.Call | |
local hook_name, no_hook_call_count = "NEVERUSETHISOK", no_hook_call_count -- yes this is important | |
for i = 1, no_hook_call_count do | |
call(hook_name, gm) | |
end | |
return no_hook_call_count | |
end, | |
CallInvalid = function(lib) | |
local call, add = lib.Call, lib.Add | |
local hook_name, invalid_call_count = "NEVERUSETHISOKENTS", invalid_call_count -- yes this is important | |
local function nop() end | |
local invalid = {} | |
local valid = {} | |
for i = 1, 25 do | |
invalid[i] = {IsValid = function() return false end} | |
valid[i] = {IsValid = function() return true end} | |
end | |
for i = 1, invalid_call_count do | |
for i2 = 1, 25 do -- very extreme case | |
add(hook_name, invalid[i2], nop) | |
add(hook_name, valid[i2], nop) | |
end | |
call(hook_name) | |
end | |
return invalid_call_count | |
end, | |
Verify = function(hook) | |
local HOOK_ID = "VERIFY_HOOK" | |
local call_count = 0 | |
local function add() call_count = call_count + 1 end | |
hook.Add(HOOK_ID, HOOK_ID, add) | |
hook.Call(HOOK_ID) | |
assert(call_count == 1, "Call count not sane") | |
call_count = 0 | |
hook.Remove(HOOK_ID, HOOK_ID) | |
hook.Call(HOOK_ID) | |
assert(call_count == 0, "Call count not sane after remove") | |
call_count = 0 | |
hook.Add(HOOK_ID, HOOK_ID, add) | |
hook.Call(HOOK_ID) | |
assert(call_count == 1, "Call count not sane after readd") | |
call_count = 0 | |
hook.Add(HOOK_ID, HOOK_ID, add) | |
hook.Call(HOOK_ID) | |
assert(call_count == 1, "Call count not sane after duped add") | |
call_count = 0 | |
local t = {IsValid = function() return true end} | |
hook.Add(HOOK_ID, t, function(self) | |
assert(t == self, "did not pass object name to hook") | |
add() | |
end) | |
hook.Call(HOOK_ID) | |
assert(call_count == 2, "Call count not sane after calling IsValid") | |
--[[ | |
hook.Add(HOOK_ID, HOOK_ID) | |
assert(hook.GetTable()[HOOK_ID][HOOK_ID], "Removed instead of returning") | |
call_count = 0 | |
hook.Call(HOOK_ID) | |
assert(call_count == 2, "Wrong call count after add with nil function") | |
]] | |
hook.Remove(HOOK_ID, HOOK_ID) | |
call_count = 0 | |
hook.Call(HOOK_ID) | |
assert(call_count == 1, "Call count not one") | |
hook.Remove(HOOK_ID, t) | |
call_count = 0 | |
hook.Call(HOOK_ID) | |
assert(call_count == 0, "Call count not zero") | |
call_count = 0 | |
hook.Add(HOOK_ID, HOOK_ID, add) | |
t = {IsValid = function() return true end} | |
hook.Add(HOOK_ID, t, add) | |
hook.Add(HOOK_ID, {IsValid = function() return false end}, add) | |
hook.Call(HOOK_ID) | |
assert(call_count == 2, "Call count not two after adding isvalids "..call_count) | |
call_count = 0 | |
hook.Remove(HOOK_ID, HOOK_ID) | |
hook.Add(HOOK_ID, {IsValid = function() return false end}, add) | |
hook.Add(HOOK_ID, t, add) | |
hook.Call(HOOK_ID) | |
assert(call_count == 1, "Call count not one after adding isvalids "..call_count) | |
call_count = 0 | |
hook.Add(HOOK_ID, {IsValid = function() return false end}, add) | |
hook.Call(HOOK_ID) | |
assert(call_count == 1, "Call count not one after adding invalid at end "..call_count) | |
call_count = 0 | |
hook.Call(HOOK_ID) | |
assert(call_count == 1, "Call count not one after removing invalid at end"..call_count) | |
call_count = 0 | |
hook.Add(HOOK_ID, t, add) | |
pcall(hook.Add, HOOK_ID, HOOK_ID) | |
hook.Remove(HOOK_ID, HOOK_ID) | |
hook.Call(HOOK_ID) | |
assert(call_count == 1, "Call count not one after instantly removing "..call_count) | |
call_count = 0 | |
hook.Remove(HOOK_ID, t) | |
assert(call_count == 0, "Call count not zero after removing all hooks") | |
hook.Add(HOOK_ID, HOOK_ID, function() | |
add() | |
hook.Remove(HOOK_ID, HOOK_ID) | |
hook.Call(HOOK_ID) | |
assert(call_count == 1, "Call count not 1 after removing inside and calling again "..call_count) | |
hook.Add(HOOK_ID, HOOK_ID, add) | |
hook.Call(HOOK_ID) | |
assert(call_count == 2, "Call count not 2 after removing inside and calling then adding again "..call_count) | |
end) | |
local GM | |
GM = { | |
[HOOK_ID] = function(self) | |
assert(self == GM, "GM not passed") | |
add() | |
end | |
} | |
call_count = 0 | |
hook.Call(HOOK_ID, GM) | |
assert(call_count == 3, "Call count not 3 in final test "..call_count) | |
hook.Remove(HOOK_ID, HOOK_ID) | |
return 1, true | |
end, | |
All = function(self, lib) | |
local bench_time = SysTime | |
for i = 1, #hooks do | |
lib.Add(hook_name, tostring(i), hooks[i]) | |
end | |
self.Verify(lib) | |
local rets = {} | |
for _, k in ipairs { "CallInvalid", "CallGM", "CallGMOnly", "CallNoHooks", "CallNoGM" } do | |
jit.on(self[k], true) | |
local start_time = bench_time() | |
local amountofcalls, success = self[k](lib) | |
local end_time = bench_time() | |
rets[k] = { | |
Time = end_time - start_time, | |
Calls = amountofcalls, | |
Success = success | |
} | |
end | |
for i = 1, #hooks do | |
lib.Remove(hook_name, tostring(i)) | |
end | |
return rets | |
end | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- include "jit/verbose.lua" jit.verbose.on(Msg) include "hooklib/hooktests.lua"{file1 = "hooklib/linkedhook.lua", file2 = "includes/modules/hook.lua", hook1 = "linkedhook", hook2 = "hook" } jit.verbose.off() | |
return function(data) | |
assert(data.file1 and data.file2 and data.hook1 and data.hook2, "testing requires four arguments") | |
local file1, file2 = data.file1, data.file2 | |
include(file1) | |
include(file2) | |
local suite1, suite2 = include "hooklib/hooksuite.lua", include "hooklib/hooksuite.lua" | |
local hook1, hook2 = getfenv(0)[data.hook1], getfenv(0)[data.hook2] | |
assert(hook1, "hook1 failed") | |
assert(hook2, "hook2 failed") | |
print(file1.."...") | |
local score1 = suite1:All(hook1) | |
print(file2.."...") | |
local score2 = suite2:All(hook2) | |
print "\n\n\n\n\n\n\n\n" | |
print "BENCHMARK" | |
local printafter1 = (" "):rep(math.max(file1:len(), file2:len()) - file1:len()) | |
local printafter2 = (" "):rep(math.max(file1:len(), file2:len()) - file2:len()) | |
for k, v in pairs(score2) do | |
if (not v.Time) then continue end | |
local did2win = score1[k].Time > v.Time | |
print "-------------" | |
print(string.format("%s (%i calls)\n%s (%.02f%%)", k, v.Calls or 0, did2win and file2 or file1, 100 * (1 - (did2win and score1[k].Time / v.Time or v.Time / score1[k].Time)))) | |
print(string.format("%s:%s %.09f s", file2, printafter2, v.Time)) | |
print(string.format("%s:%s %.09f s", file1, printafter1, score1[k].Time)) | |
end | |
print "-------------" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment