1
0
Fork 0
mirror of https://github.com/luau-lang/luau.git synced 2025-04-07 04:10:54 +01:00
luau/bench/bench_support.lua
Vyacheslav Egorov aafea36235
Fixed the backwards compatible benchmark support library require ()
Previous benchmark require fix wasn't actually working correctly for the
old style require (or running in Lua).
2023-12-04 12:48:31 -08:00

103 lines
3.6 KiB
Lua

-- This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
local bench = {}
bench.runs = 20
bench.extraRuns = 4
function bench.runCode(f, description)
-- Under Callgrind, run the test only once and measure just the execution cost
if callgrind and callgrind("running") then
if collectgarbage then collectgarbage() end
callgrind("zero")
f() -- unfortunately we can't easily separate setup cost from runtime cost in f unless it calls callgrind()
callgrind("dump", description)
return
end
local timeTable = {}
for i = 1,bench.runs + bench.extraRuns do
-- try to run GC if it's available
if collectgarbage then
pcall(function()
collectgarbage()
end)
end
local ts0 = os.clock()
local result = f()
local ts1 = os.clock()
-- If test case doesn't return a duration (if only a part of code is measured) we will measure full execution time here
if not result then
result = ts1 - ts0
end
table.insert(timeTable, result)
end
table.sort(timeTable)
for i = 1,bench.extraRuns do
table.remove(timeTable, #timeTable)
end
-- Output test name followed by each result
local report = "|><|"..description
for _,v in ipairs(timeTable) do
report = report .. "|><|" .. (v * 1000)
end
report = report .. "||_||"
print(report)
end
-- This function acts a bit like a Unix "fork" operation
-- When it is first called it clones `scriptInstance` and starts executing
-- the cloned script parented to an Actor. When the cloned script calls "runScriptCodeUnderActor"
-- it will run 'f' and print out the provided 'description'.
--
-- The function returns 'true' if it was invoked from a script running under an Actor
-- and 'false' otherwise.
--
-- Example usage:
-- local function prequire(name) local success, result = pcall(require, name); return if success then result else nil end
-- local bench = script and require(script.Parent.bench_support) or prequire("bench_support") or require("../bench_support")
-- function testFunc()
-- ...
-- end
-- bench.runScriptCodeUnderActor(script, testFunc, "test function")
function bench.runScriptCodeUnderActor(scriptInstance, f, description)
if scriptInstance:GetActor() then
-- If this function was called from an Actor script, just run the function provided using runCode
bench.runCode(f, description)
return true
else
-- If this function was not called from an Actor script, clone the script and place it under
-- Actor instance.
-- Create an Actor to run the script under
local actor = Instance.new("Actor")
-- Clone this script (i.e. the bench_support module) and place it under the Actor where
-- the script script would expect it to be when using 'require'.
local benchModule = script:Clone()
benchModule.Parent = actor
-- Clone the scriptInstance
local actorScript = scriptInstance:Clone()
-- Enable the script since `scriptInstance` may be started by roblox-cli without ever being enabled.
actorScript.Disabled = false
actorScript.Parent = actor
-- Add the actor to the workspace which will start executing the cloned script.
-- Note: the script needs to be placed under a instance that implements 'IScriptFilter'
-- (which workspace does) or it will never start executing.
actor.Parent = workspace
return false
end
end
return bench