物件效能基準測試

lua-users home
wiki

這是 Lua 中物件導向的各種方法的物件存取時間評量。主要關注原始效能速度,而非記憶體使用或物件製作時間。

程式碼

-- 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)

結果(目前的版本)

這些是目前版本的結果。所有時間為使用者的處理器模式時間(單位為秒,如果您的作業系統支援,則為秒以下的時間),反覆運算 1 億次(1e8,為預設值)。
| 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


如果您的規格有些價值,請隨時加入到以上內容。請執行它們三次,並採用平均值。

另請參閱


近期變更記錄 · 偏好設定
編輯 · 歷程
上次編輯:2012 年 2 月 25 日,凌晨 12:45 GMT (比較)