物件效能基準測試 |
|
-- Benchmarking support. do local function runbenchmark(name, code, count, ob) local f = loadstring([[ local count,ob = ... local clock = os.clock local start = clock() for i=1,count do ]] .. code .. [[ end return clock() - start ]]) io.write(f(count, ob), "\t", name, "\n") end local nameof = {} local codeof = {} local tests = {} function addbenchmark(name, code, ob) nameof[ob] = name codeof[ob] = code tests[#tests+1] = ob end function runbenchmarks(count) for _,ob in ipairs(tests) do runbenchmark(nameof[ob], codeof[ob], count, ob) end end end function makeob1() local self = {data = 0} function self:test() self.data = self.data + 1 end return self end addbenchmark("Standard (solid)", "ob:test()", makeob1()) local ob2mt = {} ob2mt.__index = ob2mt function ob2mt:test() self.data = self.data + 1 end function makeob2() return setmetatable({data = 0}, ob2mt) end addbenchmark("Standard (metatable)", "ob:test()", makeob2()) function makeob3() local self = {data = 0}; function self.test() self.data = self.data + 1 end return self end addbenchmark("Object using closures (PiL 16.4)", "ob.test()", makeob3()) function makeob4() local public = {} local data = 0 function public.test() data = data + 1 end function public.getdata() return data end function public.setdata(d) data = d end return public end addbenchmark("Object using closures (noself)", "ob.test()", makeob4()) addbenchmark("Direct Access", "ob.data = ob.data + 1", makeob1()) addbenchmark("Local Variable", "ob = ob + 1", 0) runbenchmarks(select(1,...) or 100000000)
| 2010-01-15 MikePall | Intel Core2 Duo E8400 3.00GHz | Linux x86, GCC 4.3.3 (-O2 -fomit-frame-pointer for both Lua and LuaJIT) | Lua 5.1.4 (lua objbench.lua) vs. | LuaJIT 1.1.5 (luajit -O objbench.lua) vs. | LuaJIT 2.0.0-beta2 (lj2 objbench.lua) Lua LJ1 LJ2 ----------------------------------------------------- 14.08 2.16 0.1 Standard (solid) 14.92 4.62 0.1 Standard (metatable) 14.28 2.66 0.1 Object using closures (PiL 16.4) 9.14 1.68 0.1 Object using closures (noself) 7.30 1.10 0.1 Direct Access 1.22 0.34 0.1 Local Variable | 2008-04-16 MikePall | Intel Core2 Duo E6420 2.13GHz | Linux x86, GCC 4.1.2 (-O3 -fomit-frame-pointer for both Lua and LuaJIT) | Lua 5.1.3 (lua objbench.lua) vs. LuaJIT 1.1.4 (luajit -O objbench.lua) 17.93 3.11 Standard (solid) 20.36 6.25 Standard (metatable) 19.34 3.73 Object using closures (PiL 16.4) 12.76 2.23 Object using closures (noself) 7.53 1.55 Direct Access 2.59 0.47 Local Variable | 2008-04-17 LeonardoMaciel | Intel Core 2 Duo T7200 2.00 GHz | WinXP, MSVC9 (VS 2008) | Lua 5.1.3 (using luavs.bat) vs. LuaJIT 1.1.4 (using luavs.bat) | [NOTE: this measurement probably didn't use luajit -O] 17.52 10.78 Standard (solid) 19.74 12.55 Standard (metatable) 18.31 10.88 Object using closures (PiL 16.4) 14.20 5.09 Object using closures (noself) 7.99 5.94 Direct Access 1.70 0.41 Local Variable | 2008-04-19 DougCurrie | Pentium M 2.00 GHz | WinXP, GCC 3.4.5 (mingw special) | Lua 5.1.3 (from wxLua build) vs. LuaJIT 1.1.4 (luajit -O objbench.lua) 28.68 4.76 Standard (solid) 31.23 9.49 Standard (metatable) 30.32 5.38 Object using closures (PiL 16.4) 19.60 3.27 Object using closures (noself) 12.47 2.26 Direct Access 2.72 0.51 Local Variable <--- Add your results here if you like. <--- Please indicate the date and your name or wiki page. <--- Add your CPU, OS, compiler and Lua and/or LuaJIT version.
Windows XP SP2 Intel P4 1.8a Standard (solid) Time: 34 Standard (metatable) Time: 37 Object using closures (PiL 16.4) Time: 40 Object using closures (noself) Time: 29 Direct Access Time: 19
Windows XP x64 SP1 AMD Athlon64 3500+ (64-bit Lua) Standard (solid) Time: 22 Standard (metatable) Time: 23 Object using closures (PiL 16.4) Time: 25 Object using closures (noself) Time: 18 Direct Access Time: 11
Windows Vista Ultimate(32bit), AMD Athlon X2 4200+ (Vanilla Lua 5.1.1 / LuaJIT 1.1.2) Standard (solid) Time: 26 / 11 Standard (metatable) Time: 29 / 15 Object using closures (PiL 16.4) Time: 30 / 12 Object using closures (noself) Time: 20 / 6 Direct Access Time: 13 / 8
Linux Xubuntu Feisty Fawn(32bit), Intel P4 Celeron 2.4ghz (Vanilla Lua 5.1.1) Standard (solid) Time: 34 Standard (metatable) Time: 38 Object using closures (PiL 16.4) Time: 40 Object using closures (noself) Time: 25 Direct Access Time: 20
Windows XP Prof. SP2, Intel PIII 500mhz (Vanilla Lua 5.1.1 / LuaJIT 1.1.2) Standard (solid) Time: 133 / 60 Standard (metatable) Time: 146 / 76 Object using closures (PiL 16.4) Time: 147 / 64 Object using closures (noself) Time: 99 / 32 Direct Access Time: 67 / 36
取得表格的區域副本的直接存取方式是目前為止執行事情最快的途徑(正如預期)。它可用作其他部分的參考。
noself 方法在此為第二快的。它完全仰賴閉包和在閉包中定義的區域變數,只回傳公開介面。如果修改測試以在每個方法呼叫中加入 10 次新增,則它可能會比直接存取的執行速度更快,因為這能減少函式呼叫的額外負載。noself 和 PiL 16.4 方法是唯一兩個支援私有範圍變數的方法。
其他方法的執行速度都比標準直接存取慢。元表格方法會因為需要額外查詢而讓作業更複雜,但其執行速度仍與 PiL 16.4 方法相當。
PiL 16.4 中提及的方法會加入私有範圍優勢並使用閉包來儲存自我,但這遠不及 Lua 中使用適當「自我」的最佳化快速。
最後要說明的一點是:基準測試程式碼的早期版本未取得物件的區域參考(而是索引全域表格)。這讓所有事情都受影響數秒,最主要的是直接存取 - 時間が 2 倍。
希望這能有幫助 - AA