From 50311518ffef3ddca12e628abfb1b952e47f3278 Mon Sep 17 00:00:00 2001 From: xfy Date: Sun, 12 Apr 2026 13:04:03 +0800 Subject: [PATCH] =?UTF-8?q?test(lua):=20=E6=B7=BB=E5=8A=A0=E5=8D=8F?= =?UTF-8?q?=E7=A8=8B=E5=92=8C=E5=AD=97=E8=8A=82=E7=A0=81=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=80=A7=E8=83=BD=E5=9F=BA=E5=87=86=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 测试协程创建和字节码编译开销。 Co-Authored-By: Claude Opus 4.6 --- internal/lua/lua_bench_test.go | 177 +++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 internal/lua/lua_bench_test.go diff --git a/internal/lua/lua_bench_test.go b/internal/lua/lua_bench_test.go new file mode 100644 index 0000000..1dea580 --- /dev/null +++ b/internal/lua/lua_bench_test.go @@ -0,0 +1,177 @@ +package lua + +import ( + "testing" + "time" + + glua "github.com/yuin/gopher-lua" +) + +// BenchmarkCoroutineCreation 测试协程创建开销 +func BenchmarkCoroutineCreation(b *testing.B) { + engine, err := NewEngine(DefaultConfig()) + if err != nil { + b.Fatal(err) + } + defer engine.Close() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + coro, err := engine.NewCoroutine(nil) + if err != nil { + b.Fatal(err) + } + engine.releaseCoroutine(coro) + } +} + +// BenchmarkBytecodeCompilation 测试字节码编译开销 +func BenchmarkBytecodeCompilation(b *testing.B) { + engine, err := NewEngine(DefaultConfig()) + if err != nil { + b.Fatal(err) + } + defer engine.Close() + + script := ` + local x = 1 + 2 + local y = x * 3 + local z = "hello " .. "world" + if y > 5 then + return z + end + return x + ` + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, err := engine.CodeCache().GetOrCompileInline(script) + if err != nil { + b.Fatal(err) + } + } +} + +// BenchmarkSharedDictSetGet 测试共享字典读写开销 +func BenchmarkSharedDictSetGet(b *testing.B) { + engine, err := NewEngine(DefaultConfig()) + if err != nil { + b.Fatal(err) + } + defer engine.Close() + + dict := engine.CreateSharedDict("bench", 10000) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + dict.Set("key", "value", 0) + dict.Get("key") + } +} + +// BenchmarkTimerCallbackThroughput 测试定时器回调吞吐量 +func BenchmarkTimerCallbackThroughput(b *testing.B) { + engine, err := NewEngine(DefaultConfig()) + if err != nil { + b.Fatal(err) + } + defer engine.Close() + + manager := engine.TimerManager() + callback := engine.L.NewFunction(func(L *glua.LState) int { + return 0 + }) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + manager.At(1*time.Millisecond, callback, nil) + } + b.StopTimer() + + // 等待所有定时器完成 + manager.WaitAll(5 * time.Second) +} + +// BenchmarkTimerCallbackWithLuaExecution 测试带 Lua 执行的定时器回调 +func BenchmarkTimerCallbackWithLuaExecution(b *testing.B) { + engine, err := NewEngine(DefaultConfig()) + if err != nil { + b.Fatal(err) + } + defer engine.Close() + + L := engine.L + ngx := L.NewTable() + L.SetGlobal("ngx", ngx) + RegisterTimerAPI(L, engine.TimerManager(), ngx) + + // 注册共享字典 API 供回调使用 + RegisterSharedDictAPI(L, engine.SharedDictManager(), ngx) + + // 简单的无 upvalue 回调 + script := ` + ngx.timer.at(0.001, function() + -- empty callback + end) + ` + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if err := L.DoString(script); err != nil { + b.Fatal(err) + } + } + b.StopTimer() + + // 等待所有回调执行完成 + time.Sleep(100 * time.Millisecond) +} + +// BenchmarkUpvalueDetection 测试 upvalue 检测开销 +func BenchmarkUpvalueDetection(b *testing.B) { + engine, err := NewEngine(DefaultConfig()) + if err != nil { + b.Fatal(err) + } + defer engine.Close() + + L := engine.L + ngx := L.NewTable() + L.SetGlobal("ngx", ngx) + RegisterTimerAPI(L, engine.TimerManager(), ngx) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + // 尝试注册带有 upvalue 的回调(应该被拒绝) + err := L.DoString(` + local x = 42 + local ok, err = ngx.timer.at(1, function() return x end) + `) + if err == nil { + // 错误可能被 Lua 内部处理,检查返回值 + } + } +} + +// BenchmarkTimerGracefulShutdown 测试优雅关闭开销 +func BenchmarkTimerGracefulShutdown(b *testing.B) { + for i := 0; i < b.N; i++ { + engine, err := NewEngine(DefaultConfig()) + if err != nil { + b.Fatal(err) + } + + manager := engine.TimerManager() + callback := engine.L.NewFunction(func(L *glua.LState) int { + return 0 + }) + + // 创建一些定时器 + for j := 0; j < 10; j++ { + manager.At(1*time.Millisecond, callback, nil) + } + + // 关闭引擎(包含优雅关闭) + engine.Close() + } +}