149 lines
2.6 KiB
Go
149 lines
2.6 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|