package luajit_bench import ( "testing" luajit "git.sharkk.net/Sky/LuaJIT-to-Go" ) // BenchmarkSimpleDoString benchmarks direct execution of a simple expression func BenchmarkSimpleDoString(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() code := "local x = 1 + 1" b.ResetTimer() for i := 0; i < b.N; i++ { if err := state.DoString(code); err != nil { b.Fatalf("DoString failed: %v", err) } } } // BenchmarkSimpleCompileAndRun benchmarks compile and run of a simple expression func BenchmarkSimpleCompileAndRun(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() code := "local x = 1 + 1" b.ResetTimer() for i := 0; i < b.N; i++ { if err := state.CompileAndRun(code, "simple"); err != nil { b.Fatalf("CompileAndRun failed: %v", err) } } } // BenchmarkSimpleCompileLoadRun benchmarks compile, load, and run of a simple expression func BenchmarkSimpleCompileLoadRun(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() code := "local x = 1 + 1" b.ResetTimer() for i := 0; i < b.N; i++ { bytecode, err := state.CompileBytecode(code, "simple") if err != nil { b.Fatalf("CompileBytecode failed: %v", err) } if err := state.LoadAndRunBytecode(bytecode, "simple"); err != nil { b.Fatalf("LoadAndRunBytecode failed: %v", err) } } } // BenchmarkSimplePrecompiledBytecode benchmarks running precompiled bytecode func BenchmarkSimplePrecompiledBytecode(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() code := "local x = 1 + 1" bytecode, err := state.CompileBytecode(code, "simple") if err != nil { b.Fatalf("CompileBytecode failed: %v", err) } b.ResetTimer() for i := 0; i < b.N; i++ { if err := state.LoadAndRunBytecode(bytecode, "simple"); err != nil { b.Fatalf("LoadAndRunBytecode failed: %v", err) } } } // BenchmarkFunctionCallDoString benchmarks direct execution of a function call func BenchmarkFunctionCallDoString(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() // Setup function setupCode := ` function add(a, b) return a + b end ` if err := state.DoString(setupCode); err != nil { b.Fatalf("Failed to set up function: %v", err) } code := "local result = add(10, 20)" b.ResetTimer() for i := 0; i < b.N; i++ { if err := state.DoString(code); err != nil { b.Fatalf("DoString failed: %v", err) } } } // BenchmarkFunctionCallPrecompiled benchmarks precompiled function call func BenchmarkFunctionCallPrecompiled(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() // Setup function setupCode := ` function add(a, b) return a + b end ` if err := state.DoString(setupCode); err != nil { b.Fatalf("Failed to set up function: %v", err) } code := "local result = add(10, 20)" bytecode, err := state.CompileBytecode(code, "call") if err != nil { b.Fatalf("CompileBytecode failed: %v", err) } b.ResetTimer() for i := 0; i < b.N; i++ { if err := state.LoadAndRunBytecode(bytecode, "call"); err != nil { b.Fatalf("LoadAndRunBytecode failed: %v", err) } } } // BenchmarkLoopDoString benchmarks direct execution of a loop func BenchmarkLoopDoString(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() code := ` local sum = 0 for i = 1, 1000 do sum = sum + i end ` b.ResetTimer() for i := 0; i < b.N; i++ { if err := state.DoString(code); err != nil { b.Fatalf("DoString failed: %v", err) } } } // BenchmarkLoopPrecompiled benchmarks precompiled loop execution func BenchmarkLoopPrecompiled(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() code := ` local sum = 0 for i = 1, 1000 do sum = sum + i end ` bytecode, err := state.CompileBytecode(code, "loop") if err != nil { b.Fatalf("CompileBytecode failed: %v", err) } b.ResetTimer() for i := 0; i < b.N; i++ { if err := state.LoadAndRunBytecode(bytecode, "loop"); err != nil { b.Fatalf("LoadAndRunBytecode failed: %v", err) } } } // BenchmarkTableOperationsDoString benchmarks direct execution of table operations func BenchmarkTableOperationsDoString(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() code := ` local t = {} for i = 1, 100 do t[i] = i * 2 end local sum = 0 for i, v in ipairs(t) do sum = sum + v end ` b.ResetTimer() for i := 0; i < b.N; i++ { if err := state.DoString(code); err != nil { b.Fatalf("DoString failed: %v", err) } } } // BenchmarkTableOperationsPrecompiled benchmarks precompiled table operations func BenchmarkTableOperationsPrecompiled(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() code := ` local t = {} for i = 1, 100 do t[i] = i * 2 end local sum = 0 for i, v in ipairs(t) do sum = sum + v end ` bytecode, err := state.CompileBytecode(code, "table") if err != nil { b.Fatalf("CompileBytecode failed: %v", err) } b.ResetTimer() for i := 0; i < b.N; i++ { if err := state.LoadAndRunBytecode(bytecode, "table"); err != nil { b.Fatalf("LoadAndRunBytecode failed: %v", err) } } } // BenchmarkGoFunctionCall benchmarks calling a Go function from Lua func BenchmarkGoFunctionCall(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() // Register a simple Go function add := func(s *luajit.State) int { a := s.ToNumber(1) b := s.ToNumber(2) s.PushNumber(a + b) return 1 } if err := state.RegisterGoFunction("add", add); err != nil { b.Fatalf("RegisterGoFunction failed: %v", err) } code := "local result = add(10, 20)" bytecode, err := state.CompileBytecode(code, "gofunc") if err != nil { b.Fatalf("CompileBytecode failed: %v", err) } b.ResetTimer() for i := 0; i < b.N; i++ { if err := state.LoadAndRunBytecode(bytecode, "gofunc"); err != nil { b.Fatalf("LoadAndRunBytecode failed: %v", err) } } } // BenchmarkComplexScript benchmarks a more complex script func BenchmarkComplexScript(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() code := ` -- Define a simple class local Class = {} Class.__index = Class function Class.new(x, y) local self = setmetatable({}, Class) self.x = x or 0 self.y = y or 0 return self end function Class:move(dx, dy) self.x = self.x + dx self.y = self.y + dy return self end function Class:getPosition() return self.x, self.y end -- Create instances and operate on them local instances = {} for i = 1, 50 do instances[i] = Class.new(i, i*2) end local result = 0 for i, obj in ipairs(instances) do obj:move(i, -i) local x, y = obj:getPosition() result = result + x + y end return result ` b.ResetTimer() for i := 0; i < b.N; i++ { if _, err := state.ExecuteWithResult(code); err != nil { b.Fatalf("ExecuteWithResult failed: %v", err) } } } // BenchmarkComplexScriptPrecompiled benchmarks a precompiled complex script func BenchmarkComplexScriptPrecompiled(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() code := ` -- Define a simple class local Class = {} Class.__index = Class function Class.new(x, y) local self = setmetatable({}, Class) self.x = x or 0 self.y = y or 0 return self end function Class:move(dx, dy) self.x = self.x + dx self.y = self.y + dy return self end function Class:getPosition() return self.x, self.y end -- Create instances and operate on them local instances = {} for i = 1, 50 do instances[i] = Class.new(i, i*2) end local result = 0 for i, obj in ipairs(instances) do obj:move(i, -i) local x, y = obj:getPosition() result = result + x + y end return result ` bytecode, err := state.CompileBytecode(code, "complex") if err != nil { b.Fatalf("CompileBytecode failed: %v", err) } b.ResetTimer() for i := 0; i < b.N; i++ { if err := state.LoadBytecode(bytecode, "complex"); err != nil { b.Fatalf("LoadBytecode failed: %v", err) } if err := state.RunBytecodeWithResults(1); err != nil { // Assuming this method exists to get the return value b.Fatalf("RunBytecodeWithResults failed: %v", err) } state.Pop(1) // Pop the result } } // BenchmarkMultipleExecutions benchmarks executing the same bytecode multiple times func BenchmarkMultipleExecutions(b *testing.B) { state := luajit.New() if state == nil { b.Fatal("Failed to create Lua state") } defer state.Close() // Setup a stateful environment setupCode := ` counter = 0 function increment(amount) counter = counter + (amount or 1) return counter end ` if err := state.DoString(setupCode); err != nil { b.Fatalf("Failed to set up environment: %v", err) } // Compile the function call code := "return increment(5)" bytecode, err := state.CompileBytecode(code, "increment") if err != nil { b.Fatalf("CompileBytecode failed: %v", err) } b.ResetTimer() for i := 0; i < b.N; i++ { if err := state.LoadBytecode(bytecode, "increment"); err != nil { b.Fatalf("LoadBytecode failed: %v", err) } if err := state.RunBytecodeWithResults(1); err != nil { // Assuming this method exists b.Fatalf("RunBytecodeWithResults failed: %v", err) } state.Pop(1) // Pop the result } }