測試環境
- Lua 5.1 / LuaJIT 2.1
- C++ 宿主調用 Lua 函數,測量空函數調用開銷。
實驗設計與結果
| 實驗 | Lua 函數簽名 | 1000 次調用耗時 | 單次調用估算 |
| 1 | function test(x1..x9) end (8+ 參數,含 table) | ~35 ms | 0.035 ms |
| 2 | function test(x1) end | ~16 ms | 0.016 ms |
| 3 | function test(x1) Chat(x1..x7) end (Lua→C++ 回調 7 參數) | ~31 ms | 0.031 ms (含回調) |
| 4 | function test(x1,x2) end | ~16 ms | 0.016 ms |
| 5 | function test(x1,x2,x3) end | ~16 ms | 0.016 ms |
| 6 | function test(x1..x7) end | ~16 ms | 0.016 ms |
結論
- Lua 虛擬機進入/退出開銷約 **0.014–0.016 ms**(~14–16 μs)。
- 參數壓棧/出棧開銷極小(<1 μs),7 參數與 1 參數幾乎無差異。
- Lua 調用 C++ 函數(回調)額外增加 ~15 μs,總計 ~30 μs。
- 實際遊戲邏輯中,Lua 端計算開銷通常遠大於調用開銷。
測試代碼框架
// 伪代碼框架
lua_State* L = luaL_newstate();
luaL_dostring(L, "function test(...) end"); // 定義被測函數
auto start = chrono::high_resolution_clock::now();
for (int i=0;i<1000;++i) {
lua_getglobal(L, "test");
// push 參數...
lua_pcall(L, nargs, 0, 0);
}
auto end = chrono::high_resolution_clock::now();
cout << chrono::duration_cast(end-start).count() << "ms\n";
建議
- 熱點路徑盡量在 C++ 完成,Lua 用於配置/腳本邏輯。
- 批量操作時,考慮一次調用傳 table 而非多次調用。
- 使用 LuaJIT 可進一步降低調用開銷(JIT 編譯後可內聯)。