LuaJIT-to-Go/benchmark/main.go

149 lines
2.6 KiB
Go
Raw Normal View History

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)
}
}
}