-- This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details1local bench = {}23bench.runs = 204bench.extraRuns = 456function bench.runCode(f, description)7-- Under Callgrind, run the test only once and measure just the execution cost8if callgrind and callgrind("running") then9if collectgarbage then collectgarbage() end1011callgrind("zero")12f() -- unfortunately we can't easily separate setup cost from runtime cost in f unless it calls callgrind()13callgrind("dump", description)14return15end1617local timeTable = {}1819for i = 1,bench.runs + bench.extraRuns do20-- try to run GC if it's available21if collectgarbage then22pcall(function()23collectgarbage()24end)25end2627local ts0 = os.clock()2829local result = f()3031local ts1 = os.clock()3233-- If test case doesn't return a duration (if only a part of code is measured) we will measure full execution time here34if not result then35result = ts1 - ts036end3738table.insert(timeTable, result)39end4041table.sort(timeTable)4243for i = 1,bench.extraRuns do44table.remove(timeTable, #timeTable)45end4647-- Output test name followed by each result48local report = "|><|"..description4950for _,v in ipairs(timeTable) do51report = report .. "|><|" .. (v * 1000)52end5354report = report .. "||_||"5556print(report)57end5859-- This function acts a bit like a Unix "fork" operation60-- When it is first called it clones `scriptInstance` and starts executing61-- the cloned script parented to an Actor. When the cloned script calls "runScriptCodeUnderActor"62-- it will run 'f' and print out the provided 'description'.63--64-- The function returns 'true' if it was invoked from a script running under an Actor65-- and 'false' otherwise.66--67-- Example usage:68-- local function prequire(name) local success, result = pcall(require, name); return success and result end69-- local bench = script and require(script.Parent.bench_support) or prequire("bench_support") or require("../bench_support")70-- function testFunc()71-- ...72-- end73-- bench.runScriptCodeUnderActor(script, testFunc, "test function")74function bench.runScriptCodeUnderActor(scriptInstance, f, description)75if scriptInstance:GetActor() then76-- If this function was called from an Actor script, just run the function provided using runCode77bench.runCode(f, description)78return true79else80-- If this function was not called from an Actor script, clone the script and place it under81-- Actor instance.8283-- Create an Actor to run the script under84local actor = Instance.new("Actor")85-- Clone this script (i.e. the bench_support module) and place it under the Actor where86-- the script script would expect it to be when using 'require'.87local benchModule = script:Clone()88benchModule.Parent = actor89-- Clone the scriptInstance90local actorScript = scriptInstance:Clone()91-- Enable the script since `scriptInstance` may be started by roblox-cli without ever being enabled.92actorScript.Disabled = false93actorScript.Parent = actor94-- Add the actor to the workspace which will start executing the cloned script.95-- Note: the script needs to be placed under a instance that implements 'IScriptFilter'96-- (which workspace does) or it will never start executing.97actor.Parent = workspace98return false99end100end101102return bench103104105