package main import ( "fmt" "time" luajit "git.sharkk.net/Sky/LuaJIT-to-Go" ) type benchCase struct { name string code string } var cases = []benchCase{ { name: "Simple Addition", code: `return 1 + 1`, }, { name: "Loop Sum", code: ` local sum = 0 for i = 1, 1000 do sum = sum + i end return sum `, }, { name: "Function Call", code: ` local result = 0 for i = 1, 100 do result = result + i end return result `, }, { name: "Table Creation", code: ` local t = {} for i = 1, 100 do t[i] = i * 2 end return t[50] `, }, { name: "String Operations", code: ` local s = "hello" for i = 1, 10 do s = s .. " world" end return #s `, }, } func runBenchmark(L *luajit.State, code string, duration time.Duration) (time.Duration, int64) { start := time.Now() deadline := start.Add(duration) var ops int64 for time.Now().Before(deadline) { if err := L.DoString(code); err != nil { fmt.Printf("Error executing code: %v\n", err) return 0, 0 } L.Pop(1) ops++ } return time.Since(start), ops } func runBytecodeTest(L *luajit.State, code string, duration time.Duration) (time.Duration, int64) { // First compile the bytecode bytecode, err := L.CompileBytecode(code, "bench") if err != nil { fmt.Printf("Error compiling bytecode: %v\n", err) return 0, 0 } start := time.Now() deadline := start.Add(duration) var ops int64 for time.Now().Before(deadline) { if err := L.LoadBytecode(bytecode, "bench"); err != nil { fmt.Printf("Error executing bytecode: %v\n", err) return 0, 0 } ops++ } return time.Since(start), ops } func benchmarkCase(newState func() *luajit.State, bc benchCase) { fmt.Printf("\n%s:\n", bc.name) // Direct execution benchmark L := newState() if L == nil { fmt.Printf(" Failed to create Lua state\n") return } execTime, ops := runBenchmark(L, bc.code, 2*time.Second) L.Close() if ops > 0 { opsPerSec := float64(ops) / execTime.Seconds() fmt.Printf(" Direct: %.0f ops/sec\n", opsPerSec) } // Bytecode execution benchmark L = newState() if L == nil { fmt.Printf(" Failed to create Lua state\n") return } execTime, ops = runBytecodeTest(L, bc.code, 2*time.Second) L.Close() if ops > 0 { opsPerSec := float64(ops) / execTime.Seconds() fmt.Printf(" Bytecode: %.0f ops/sec\n", opsPerSec) } } func main() { modes := []struct { name string newState func() *luajit.State }{ {"Safe", luajit.NewSafe}, {"Unsafe", luajit.New}, } for _, mode := range modes { fmt.Printf("\n=== %s Mode ===\n", mode.name) for _, c := range cases { benchmarkCase(mode.newState, c) } } }