package luajit import ( "testing" ) var benchCases = []struct { name string code string }{ { name: "SimpleAddition", code: `return 1 + 1`, }, { name: "LoopSum", code: ` local sum = 0 for i = 1, 1000 do sum = sum + i end return sum `, }, { name: "FunctionCall", code: ` local result = 0 for i = 1, 100 do result = result + i end return result `, }, { name: "TableCreation", code: ` local t = {} for i = 1, 100 do t[i] = i * 2 end return t[50] `, }, { name: "StringOperations", code: ` local s = "hello" for i = 1, 10 do s = s .. " world" end return #s `, }, } func BenchmarkLuaDirectExecution(b *testing.B) { for _, bc := range benchCases { b.Run(bc.name, func(b *testing.B) { L := New() if L == nil { b.Fatal("Failed to create Lua state") } defer L.Close() // First verify we can execute the code if err := L.DoString(bc.code); err != nil { b.Fatalf("Failed to execute test code: %v", err) } L.Pop(1) // Clean up the result b.ResetTimer() for i := 0; i < b.N; i++ { // Execute string and get result nresults, err := L.ExecuteString(bc.code) if err != nil { b.Fatalf("Failed to execute code: %v", err) } L.Pop(nresults) // Clean up any results } }) } } func BenchmarkLuaBytecodeExecution(b *testing.B) { // First compile all bytecode bytecodes := make(map[string][]byte) for _, bc := range benchCases { L := New() if L == nil { b.Fatal("Failed to create Lua state") } bytecode, err := L.CompileBytecode(bc.code, bc.name) if err != nil { L.Close() b.Fatalf("Error compiling bytecode for %s: %v", bc.name, err) } bytecodes[bc.name] = bytecode L.Close() } for _, bc := range benchCases { b.Run(bc.name, func(b *testing.B) { L := New() if L == nil { b.Fatal("Failed to create Lua state") } defer L.Close() bytecode := bytecodes[bc.name] // First verify we can execute the bytecode if err := L.LoadBytecode(bytecode, bc.name); err != nil { b.Fatalf("Failed to execute test bytecode: %v", err) } b.ResetTimer() b.SetBytes(int64(len(bytecode))) // Track bytecode size in benchmarks for i := 0; i < b.N; i++ { if err := L.LoadBytecode(bytecode, bc.name); err != nil { b.Fatalf("Error executing bytecode: %v", err) } } }) } } func BenchmarkTableOperations(b *testing.B) { testData := map[string]interface{}{ "number": 42.0, "string": "hello", "bool": true, "nested": map[string]interface{}{ "value": 123.0, "array": []float64{1.1, 2.2, 3.3}, }, } b.Run("PushTable", func(b *testing.B) { L := New() if L == nil { b.Fatal("Failed to create Lua state") } defer L.Close() // First verify we can push the table if err := L.PushTable(testData); err != nil { b.Fatalf("Failed to push initial table: %v", err) } L.Pop(1) b.ResetTimer() for i := 0; i < b.N; i++ { if err := L.PushTable(testData); err != nil { b.Fatalf("Failed to push table: %v", err) } L.Pop(1) } }) b.Run("ToTable", func(b *testing.B) { L := New() if L == nil { b.Fatal("Failed to create Lua state") } defer L.Close() // Keep a table on the stack for repeated conversions if err := L.PushTable(testData); err != nil { b.Fatalf("Failed to push initial table: %v", err) } b.ResetTimer() for i := 0; i < b.N; i++ { if _, err := L.ToTable(-1); err != nil { b.Fatalf("Failed to convert table: %v", err) } } }) } func BenchmarkValueConversion(b *testing.B) { testValues := []struct { name string value interface{} }{ {"Number", 42.0}, {"String", "hello world"}, {"Boolean", true}, {"Nil", nil}, } for _, tv := range testValues { b.Run("Push"+tv.name, func(b *testing.B) { L := New() if L == nil { b.Fatal("Failed to create Lua state") } defer L.Close() // First verify we can push the value if err := L.PushValue(tv.value); err != nil { b.Fatalf("Failed to push initial value: %v", err) } L.Pop(1) b.ResetTimer() for i := 0; i < b.N; i++ { if err := L.PushValue(tv.value); err != nil { b.Fatalf("Failed to push value: %v", err) } L.Pop(1) } }) b.Run("To"+tv.name, func(b *testing.B) { L := New() if L == nil { b.Fatal("Failed to create Lua state") } defer L.Close() // Keep a value on the stack for repeated conversions if err := L.PushValue(tv.value); err != nil { b.Fatalf("Failed to push initial value: %v", err) } b.ResetTimer() for i := 0; i < b.N; i++ { if _, err := L.ToValue(-1); err != nil { b.Fatalf("Failed to convert value: %v", err) } } }) } }