1
0

more attempts at batching

This commit is contained in:
Sky Johnson 2025-07-02 11:59:39 -05:00
parent 3a4cb27473
commit 081fb0b7de
4 changed files with 1199 additions and 603 deletions

828
batch.go

File diff suppressed because it is too large Load Diff

View File

@ -470,3 +470,316 @@ func BenchmarkMultipleExecutions(b *testing.B) {
} }
}) })
} }
// BenchmarkBatchVsIndividualTableFields compares batch vs individual table field setting
func BenchmarkBatchVsIndividualTableFields(b *testing.B) {
b.Run("Individual", func(b *testing.B) {
state := luajit.New()
defer state.Close()
fields := map[string]string{
"name": "test",
"version": "1.0",
"description": "benchmark",
"author": "user",
"license": "MIT",
"homepage": "example.com",
"repository": "git://example.com",
"keywords": "test,bench",
}
TrackMemoryUsage(b, "individual-fields", func() {
for i := 0; i < b.N; i++ {
tb := state.NewTableBuilder()
for k, v := range fields {
tb.SetString(k, v)
}
tb.Build()
state.Pop(1)
}
})
})
b.Run("Batch", func(b *testing.B) {
state := luajit.New()
defer state.Close()
fields := map[string]string{
"name": "test",
"version": "1.0",
"description": "benchmark",
"author": "user",
"license": "MIT",
"homepage": "example.com",
"repository": "git://example.com",
"keywords": "test,bench",
}
TrackMemoryUsage(b, "batch-fields", func() {
for i := 0; i < b.N; i++ {
btb := state.NewBatchTableBuilder()
for k, v := range fields {
btb.SetString(k, v)
}
btb.Build()
state.Pop(1)
}
})
})
}
// BenchmarkBatchVsIndividualArrays compares batch vs individual array creation
func BenchmarkBatchVsIndividualArrays(b *testing.B) {
intArray := make([]int, 100)
for i := range intArray {
intArray[i] = i * 2
}
b.Run("Individual", func(b *testing.B) {
state := luajit.New()
defer state.Close()
TrackMemoryUsage(b, "individual-array", func() {
for i := 0; i < b.N; i++ {
state.CreateTable(len(intArray), 0)
for j, v := range intArray {
state.PushNumber(float64(j + 1))
state.PushNumber(float64(v))
state.SetTable(-3)
}
state.Pop(1)
}
})
})
b.Run("Batch", func(b *testing.B) {
state := luajit.New()
defer state.Close()
TrackMemoryUsage(b, "batch-array", func() {
for i := 0; i < b.N; i++ {
state.BatchPushIntArray(intArray)
state.Pop(1)
}
})
})
}
// BenchmarkBatchVsIndividualGlobals compares batch vs individual global variable setting
func BenchmarkBatchVsIndividualGlobals(b *testing.B) {
globals := map[string]string{
"APP_NAME": "myapp",
"APP_VERSION": "1.0.0",
"APP_ENVIRONMENT": "production",
"APP_DEBUG": "false",
"APP_URL": "https://example.com",
"APP_TIMEZONE": "UTC",
"DB_HOST": "localhost",
"DB_PORT": "5432",
}
b.Run("Individual", func(b *testing.B) {
state := luajit.New()
defer state.Close()
TrackMemoryUsage(b, "individual-globals", func() {
for i := 0; i < b.N; i++ {
for k, v := range globals {
state.PushString(v)
state.SetGlobal(k)
}
}
})
})
b.Run("Batch", func(b *testing.B) {
state := luajit.New()
defer state.Close()
TrackMemoryUsage(b, "batch-globals", func() {
for i := 0; i < b.N; i++ {
state.BatchSetGlobals(globals)
}
})
})
}
// BenchmarkBatchVsIndividualTableReads compares batch vs individual table field reading
func BenchmarkBatchVsIndividualTableReads(b *testing.B) {
state := luajit.New()
defer state.Close()
// Setup test table
setupCode := `
config = {
database = {host = "localhost", port = 5432, name = "mydb"},
server = {host = "0.0.0.0", port = 8080, ssl = true},
logging = {level = "info", file = "/var/log/app.log"},
cache = {enabled = true, ttl = 300, size = 1000}
}
`
if err := state.DoString(setupCode); err != nil {
b.Fatalf("Setup failed: %v", err)
}
keys := []string{"database", "server", "logging", "cache"}
b.Run("Individual", func(b *testing.B) {
TrackMemoryUsage(b, "individual-reads", func() {
for i := 0; i < b.N; i++ {
state.GetGlobal("config")
values := make(map[string]any)
for _, key := range keys {
state.GetField(-1, key)
if val, err := state.ToValue(-1); err == nil {
values[key] = val
}
state.Pop(1)
}
state.Pop(1)
_ = values
}
})
})
b.Run("Batch", func(b *testing.B) {
TrackMemoryUsage(b, "batch-reads", func() {
for i := 0; i < b.N; i++ {
state.GetGlobal("config")
reader := state.NewBatchTableReader(-1)
values, _ := reader.ReadFields(keys)
state.Pop(1)
_ = values
}
})
})
}
// BenchmarkBatchValuePusher compares batch vs individual value pushing
func BenchmarkBatchValuePusher(b *testing.B) {
values := []any{"hello", 42, true, 3.14, "world", 100, false, 2.718}
b.Run("Individual", func(b *testing.B) {
state := luajit.New()
defer state.Close()
TrackMemoryUsage(b, "individual-push", func() {
for i := 0; i < b.N; i++ {
for _, v := range values {
state.PushValue(v)
}
state.Pop(len(values))
}
})
})
b.Run("Batch", func(b *testing.B) {
state := luajit.New()
defer state.Close()
TrackMemoryUsage(b, "batch-push", func() {
for i := 0; i < b.N; i++ {
pusher := state.NewBatchValuePusher()
for _, v := range values {
pusher.Add(v)
}
pusher.Push()
state.Pop(len(values))
}
})
})
}
// BenchmarkBatchTypeChecking compares batch vs individual type checking
func BenchmarkBatchTypeChecking(b *testing.B) {
state := luajit.New()
defer state.Close()
// Setup test values on stack
state.PushString("hello")
state.PushNumber(42)
state.PushBoolean(true)
state.PushNil()
checks := []luajit.TypeCheck{
{Index: 1, ExpectedType: luajit.TypeString},
{Index: 2, ExpectedType: luajit.TypeNumber},
{Index: 3, ExpectedType: luajit.TypeBoolean},
{Index: 4, ExpectedType: luajit.TypeNil},
}
b.Run("Individual", func(b *testing.B) {
TrackMemoryUsage(b, "individual-check", func() {
for i := 0; i < b.N; i++ {
for _, check := range checks {
if state.GetType(check.Index) != check.ExpectedType {
b.Fatal("Type mismatch")
}
}
}
})
})
b.Run("Batch", func(b *testing.B) {
TrackMemoryUsage(b, "batch-check", func() {
for i := 0; i < b.N; i++ {
if err := state.BatchCheckTypes(checks); err != nil {
b.Fatal("Type check failed:", err)
}
}
})
})
}
// BenchmarkBatchGlobalManager benchmarks the batch global manager
func BenchmarkBatchGlobalManager(b *testing.B) {
state := luajit.New()
defer state.Close()
setGlobals := map[string]string{
"VAR1": "value1",
"VAR2": "value2",
"VAR3": "value3",
"VAR4": "value4",
}
getGlobals := []string{"VAR1", "VAR2", "VAR3", "VAR4"}
b.Run("Individual", func(b *testing.B) {
TrackMemoryUsage(b, "individual-global-mgmt", func() {
for i := 0; i < b.N; i++ {
// Set globals
for k, v := range setGlobals {
state.PushString(v)
state.SetGlobal(k)
}
// Get globals
results := make(map[string]any)
for _, name := range getGlobals {
state.GetGlobal(name)
if val, err := state.ToValue(-1); err == nil {
results[name] = val
}
state.Pop(1)
}
_ = results
}
})
})
b.Run("Batch", func(b *testing.B) {
TrackMemoryUsage(b, "batch-global-mgmt", func() {
for i := 0; i < b.N; i++ {
mgr := state.NewBatchGlobalManager()
for k, v := range setGlobals {
mgr.QueueSet(k, v)
}
for _, name := range getGlobals {
mgr.QueueGet(name)
}
results, _ := mgr.Execute()
_ = results
}
})
})
}

View File

@ -136,3 +136,637 @@ func BenchmarkLuaBytecodeExecution(b *testing.B) {
}) })
} }
} }
// BenchmarkBatchTableOperations compares batch vs individual table operations
func BenchmarkBatchTableOperations(b *testing.B) {
testData := map[string]any{
"name": "testapp",
"version": "1.0.0",
"port": 8080,
"debug": true,
"timeout": 30.5,
"tags": []string{"web", "api", "service"},
"limits": []int{100, 200, 300, 400, 500},
}
b.Run("Individual", func(b *testing.B) {
L := luajit.New()
defer L.Close()
defer L.Cleanup()
TrackMemoryUsage(b, "table-individual", func() {
for i := 0; i < b.N; i++ {
tb := L.NewTableBuilder()
for k, v := range testData {
switch val := v.(type) {
case string:
tb.SetString(k, val)
case int:
tb.SetNumber(k, float64(val))
case bool:
tb.SetBool(k, val)
case float64:
tb.SetNumber(k, val)
default:
tb.SetTable(k, v)
}
}
tb.Build()
L.Pop(1)
}
})
})
b.Run("Batch", func(b *testing.B) {
L := luajit.New()
defer L.Close()
defer L.Cleanup()
TrackMemoryUsage(b, "table-batch", func() {
for i := 0; i < b.N; i++ {
tb := L.NewTableBuilder()
tb.BatchBuild(testData)
tb.Build()
L.Pop(1)
}
})
})
b.Run("BatchTableBuilder", func(b *testing.B) {
L := luajit.New()
defer L.Close()
defer L.Cleanup()
TrackMemoryUsage(b, "table-batch-builder", func() {
for i := 0; i < b.N; i++ {
btb := L.NewBatchTableBuilder()
for k, v := range testData {
switch val := v.(type) {
case string:
btb.SetString(k, val)
case int:
btb.SetNumber(k, float64(val))
case bool:
btb.SetBool(k, val)
case float64:
btb.SetNumber(k, val)
default:
btb.SetTable(k, v)
}
}
btb.Build()
L.Pop(1)
}
})
})
}
// BenchmarkBatchArrayOperations compares different array creation methods
func BenchmarkBatchArrayOperations(b *testing.B) {
intArray := make([]int, 50)
stringArray := make([]string, 50)
floatArray := make([]float64, 50)
boolArray := make([]bool, 50)
for i := range 50 {
intArray[i] = i * 2
stringArray[i] = "item" + string(rune('0'+i%10))
floatArray[i] = float64(i) * 1.5
boolArray[i] = i%2 == 0
}
b.Run("IntArray_Individual", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "int-array-individual", func() {
for i := 0; i < b.N; i++ {
L.PushValue(intArray)
L.Pop(1)
}
})
})
b.Run("IntArray_Batch", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "int-array-batch", func() {
for i := 0; i < b.N; i++ {
L.BatchPushIntArray(intArray)
L.Pop(1)
}
})
})
b.Run("StringArray_Individual", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "string-array-individual", func() {
for i := 0; i < b.N; i++ {
L.PushValue(stringArray)
L.Pop(1)
}
})
})
b.Run("StringArray_Batch", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "string-array-batch", func() {
for i := 0; i < b.N; i++ {
L.BatchPushStringArray(stringArray)
L.Pop(1)
}
})
})
b.Run("FloatArray_Individual", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "float-array-individual", func() {
for i := 0; i < b.N; i++ {
L.PushValue(floatArray)
L.Pop(1)
}
})
})
b.Run("FloatArray_Batch", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "float-array-batch", func() {
for i := 0; i < b.N; i++ {
L.BatchPushFloatArray(floatArray)
L.Pop(1)
}
})
})
b.Run("BoolArray_Individual", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "bool-array-individual", func() {
for i := 0; i < b.N; i++ {
L.PushValue(boolArray)
L.Pop(1)
}
})
})
b.Run("BoolArray_Batch", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "bool-array-batch", func() {
for i := 0; i < b.N; i++ {
L.BatchPushBoolArray(boolArray)
L.Pop(1)
}
})
})
}
// BenchmarkBatchGlobalOperations compares global variable operations
func BenchmarkBatchGlobalOperations(b *testing.B) {
globals := map[string]string{
"APP_NAME": "myapp",
"APP_VERSION": "1.0.0",
"APP_ENV": "production",
"DB_HOST": "localhost",
"DB_PORT": "5432",
"DB_NAME": "mydb",
"CACHE_TTL": "300",
"LOG_LEVEL": "info",
}
b.Run("Individual_Set", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "globals-individual-set", func() {
for i := 0; i < b.N; i++ {
for k, v := range globals {
L.PushString(v)
L.SetGlobal(k)
}
}
})
})
b.Run("Batch_Set", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "globals-batch-set", func() {
for i := 0; i < b.N; i++ {
L.BatchSetGlobals(globals)
}
})
})
// Setup globals for read tests
L := luajit.New()
defer L.Close()
L.BatchSetGlobals(globals)
globalNames := make([]string, 0, len(globals))
for k := range globals {
globalNames = append(globalNames, k)
}
b.Run("Individual_Get", func(b *testing.B) {
TrackMemoryUsage(b, "globals-individual-get", func() {
for i := 0; i < b.N; i++ {
values := make(map[string]any)
for _, name := range globalNames {
L.GetGlobal(name)
if val, err := L.ToValue(-1); err == nil {
values[name] = val
}
L.Pop(1)
}
_ = values
}
})
})
b.Run("Batch_Get", func(b *testing.B) {
TrackMemoryUsage(b, "globals-batch-get", func() {
for i := 0; i < b.N; i++ {
startTop := L.GetTop()
L.BatchGetGlobals(globalNames)
values := make(map[string]any, len(globalNames))
for j, name := range globalNames {
if val, err := L.ToValue(startTop + j + 1); err == nil {
values[name] = val
}
}
L.SetTop(startTop)
_ = values
}
})
})
}
// BenchmarkBatchTableReading compares table field reading methods
func BenchmarkBatchTableReading(b *testing.B) {
L := luajit.New()
defer L.Close()
// Create a complex nested table structure
setupCode := `
config = {
database = {
host = "localhost",
port = 5432,
name = "myapp",
timeout = 30,
ssl = true,
pool = {min = 5, max = 20}
},
server = {
host = "0.0.0.0",
port = 8080,
workers = 4,
timeout = 60,
ssl = false,
middleware = {"cors", "auth", "logging"}
},
cache = {
enabled = true,
ttl = 300,
size = 1000,
backend = "redis",
cluster = false
},
logging = {
level = "info",
file = "/var/log/app.log",
rotate = true,
max_size = 100,
format = "json"
}
}
`
if err := L.DoString(setupCode); err != nil {
b.Fatalf("Setup failed: %v", err)
}
topLevelKeys := []string{"database", "server", "cache", "logging"}
dbKeys := []string{"host", "port", "name", "timeout", "ssl"}
b.Run("Individual_TopLevel", func(b *testing.B) {
TrackMemoryUsage(b, "table-read-individual", func() {
for i := 0; i < b.N; i++ {
L.GetGlobal("config")
values := make(map[string]any)
for _, key := range topLevelKeys {
L.GetField(-1, key)
if val, err := L.ToValue(-1); err == nil {
values[key] = val
}
L.Pop(1)
}
L.Pop(1)
_ = values
}
})
})
b.Run("Batch_TopLevel", func(b *testing.B) {
TrackMemoryUsage(b, "table-read-batch", func() {
for i := 0; i < b.N; i++ {
L.GetGlobal("config")
reader := L.NewBatchTableReader(-1)
values, _ := reader.ReadFields(topLevelKeys)
L.Pop(1)
_ = values
}
})
})
b.Run("Individual_Nested", func(b *testing.B) {
TrackMemoryUsage(b, "nested-read-individual", func() {
for i := 0; i < b.N; i++ {
L.GetGlobal("config")
L.GetField(-1, "database")
values := make(map[string]any)
for _, key := range dbKeys {
L.GetField(-1, key)
if val, err := L.ToValue(-1); err == nil {
values[key] = val
}
L.Pop(1)
}
L.Pop(2)
_ = values
}
})
})
b.Run("Batch_Nested", func(b *testing.B) {
TrackMemoryUsage(b, "nested-read-batch", func() {
for i := 0; i < b.N; i++ {
L.GetGlobal("config")
L.GetField(-1, "database")
reader := L.NewBatchTableReader(-1)
values, _ := reader.ReadFields(dbKeys)
L.Pop(2)
_ = values
}
})
})
}
// BenchmarkBatchValuePushing compares value pushing methods
func BenchmarkBatchValuePushing(b *testing.B) {
mixedValues := []any{
"string1", 42, true, 3.14,
"string2", 100, false, 2.718,
"string3", 256, true, 1.414,
"string4", 500, false, 0.577,
}
stringValues := []any{"hello", "world", "test", "bench", "mark", "go", "lua", "jit"}
numberValues := []any{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
b.Run("Mixed_Individual", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "mixed-individual", func() {
for i := 0; i < b.N; i++ {
for _, v := range mixedValues {
L.PushValue(v)
}
L.Pop(len(mixedValues))
}
})
})
b.Run("Mixed_Batch", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "mixed-batch", func() {
for i := 0; i < b.N; i++ {
pusher := L.NewBatchValuePusher()
for _, v := range mixedValues {
pusher.Add(v)
}
pusher.Push()
L.Pop(len(mixedValues))
}
})
})
b.Run("Strings_Individual", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "strings-individual", func() {
for i := 0; i < b.N; i++ {
for _, v := range stringValues {
L.PushValue(v)
}
L.Pop(len(stringValues))
}
})
})
b.Run("Strings_Batch", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "strings-batch", func() {
for i := 0; i < b.N; i++ {
pusher := L.NewBatchValuePusher()
for _, v := range stringValues {
pusher.Add(v)
}
pusher.Push()
L.Pop(len(stringValues))
}
})
})
b.Run("Numbers_Individual", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "numbers-individual", func() {
for i := 0; i < b.N; i++ {
for _, v := range numberValues {
L.PushValue(v)
}
L.Pop(len(numberValues))
}
})
})
b.Run("Numbers_Batch", func(b *testing.B) {
L := luajit.New()
defer L.Close()
TrackMemoryUsage(b, "numbers-batch", func() {
for i := 0; i < b.N; i++ {
pusher := L.NewBatchValuePusher()
for _, v := range numberValues {
pusher.Add(v)
}
pusher.Push()
L.Pop(len(numberValues))
}
})
})
}
// BenchmarkBatchExtraction compares array extraction methods
func BenchmarkBatchExtraction(b *testing.B) {
L := luajit.New()
defer L.Close()
// Create test arrays in Lua
setupCode := `
int_array = {}
for i = 1, 100 do
int_array[i] = i * 2
end
float_array = {}
for i = 1, 100 do
float_array[i] = i * 1.5
end
string_array = {}
for i = 1, 100 do
string_array[i] = "item" .. i
end
bool_array = {}
for i = 1, 100 do
bool_array[i] = (i % 2 == 0)
end
`
if err := L.DoString(setupCode); err != nil {
b.Fatalf("Setup failed: %v", err)
}
b.Run("IntArray_Individual", func(b *testing.B) {
TrackMemoryUsage(b, "int-extract-individual", func() {
for i := 0; i < b.N; i++ {
L.GetGlobal("int_array")
result := make([]int, 100)
for j := 1; j <= 100; j++ {
L.PushNumber(float64(j))
L.GetTable(-2)
result[j-1] = int(L.ToNumber(-1))
L.Pop(1)
}
L.Pop(1)
_ = result
}
})
})
b.Run("IntArray_Batch", func(b *testing.B) {
TrackMemoryUsage(b, "int-extract-batch", func() {
for i := 0; i < b.N; i++ {
L.GetGlobal("int_array")
result, _ := L.BatchExtractIntArray(-1, 100)
L.Pop(1)
_ = result
}
})
})
b.Run("FloatArray_Individual", func(b *testing.B) {
TrackMemoryUsage(b, "float-extract-individual", func() {
for i := 0; i < b.N; i++ {
L.GetGlobal("float_array")
result := make([]float64, 100)
for j := 1; j <= 100; j++ {
L.PushNumber(float64(j))
L.GetTable(-2)
result[j-1] = L.ToNumber(-1)
L.Pop(1)
}
L.Pop(1)
_ = result
}
})
})
b.Run("FloatArray_Batch", func(b *testing.B) {
TrackMemoryUsage(b, "float-extract-batch", func() {
for i := 0; i < b.N; i++ {
L.GetGlobal("float_array")
result, _ := L.BatchExtractFloatArray(-1, 100)
L.Pop(1)
_ = result
}
})
})
b.Run("StringArray_Individual", func(b *testing.B) {
TrackMemoryUsage(b, "string-extract-individual", func() {
for i := 0; i < b.N; i++ {
L.GetGlobal("string_array")
result := make([]string, 100)
for j := 1; j <= 100; j++ {
L.PushNumber(float64(j))
L.GetTable(-2)
result[j-1] = L.ToString(-1)
L.Pop(1)
}
L.Pop(1)
_ = result
}
})
})
b.Run("StringArray_Batch", func(b *testing.B) {
TrackMemoryUsage(b, "string-extract-batch", func() {
for i := 0; i < b.N; i++ {
L.GetGlobal("string_array")
result, _ := L.BatchExtractStringArray(-1, 100)
L.Pop(1)
_ = result
}
})
})
b.Run("BoolArray_Individual", func(b *testing.B) {
TrackMemoryUsage(b, "bool-extract-individual", func() {
for i := 0; i < b.N; i++ {
L.GetGlobal("bool_array")
result := make([]bool, 100)
for j := 1; j <= 100; j++ {
L.PushNumber(float64(j))
L.GetTable(-2)
result[j-1] = L.ToBoolean(-1)
L.Pop(1)
}
L.Pop(1)
_ = result
}
})
})
b.Run("BoolArray_Batch", func(b *testing.B) {
TrackMemoryUsage(b, "bool-extract-batch", func() {
for i := 0; i < b.N; i++ {
L.GetGlobal("bool_array")
result, _ := L.BatchExtractBoolArray(-1, 100)
L.Pop(1)
_ = result
}
})
})
}

27
bench/snapshot.txt Normal file
View File

@ -0,0 +1,27 @@
cpu: AMD Ryzen 7 8845HS w/ Radeon 780M Graphics
BenchmarkSimpleDoString-16 3050360 384.6 ns/op 0 dostring-bytes/op 0 dostring-mallocs
BenchmarkSimpleCompileAndRun-16 3016736 386.8 ns/op 0 compile-run-bytes/op 0 compile-run-mallocs
BenchmarkSimpleCompileLoadRun-16 1264791 933.1 ns/op 72.00 compile-load-run-bytes/op 2529585 compile-load-run-mallocs
BenchmarkSimplePrecompiledBytecode-16 6726292 185.7 ns/op 0 precompiled-bytes/op 0 precompiled-mallocs
BenchmarkFunctionCallDoString-16 2349952 518.0 ns/op 0 func-dostring-bytes/op 0 func-dostring-mallocs
BenchmarkFunctionCallPrecompiled-16 6023224 207.9 ns/op 0 func-precompiled-bytes/op 0 func-precompiled-mallocs
BenchmarkLoopDoString-16 149439 7880 ns/op 0 loop-dostring-bytes/op 0 loop-dostring-mallocs
BenchmarkLoopPrecompiled-16 166184 6926 ns/op 0 loop-precompiled-bytes/op 0 loop-precompiled-mallocs
BenchmarkTableOperationsDoString-16 66718 17634 ns/op 0 table-dostring-bytes/op 0 table-dostring-mallocs
BenchmarkTableOperationsPrecompiled-16 74943 15629 ns/op 0 table-precompiled-bytes/op 0 table-precompiled-mallocs
BenchmarkGoFunctionCall-16 2407584 475.5 ns/op 0.001120 go-func-call-bytes/op 8.000 go-func-call-mallocs
BenchmarkComplexScript-16 37376 32377 ns/op 8.000 complex-script-bytes/op 37376 complex-script-mallocs
BenchmarkComplexScriptPrecompiled-16 50720 23908 ns/op 0 complex-precompiled-bytes/op 0 complex-precompiled-mallocs
BenchmarkMultipleExecutions-16 4314085 273.9 ns/op 0 multiple-executions-bytes/op 0 multiple-executions-mallocs
BenchmarkLuaDirectExecution/SimpleAddition-16 2614246 451.6 ns/op 0 direct-SimpleAddition-bytes/op 0 direct-SimpleAddition-mallocs
BenchmarkLuaDirectExecution/LoopSum-16 144027 8119 ns/op 0 direct-LoopSum-bytes/op 0 direct-LoopSum-mallocs
BenchmarkLuaDirectExecution/FunctionCall-16 159513 7507 ns/op 0 direct-FunctionCall-bytes/op 0 direct-FunctionCall-mallocs
BenchmarkLuaDirectExecution/TableCreation-16 134306 9002 ns/op 0 direct-TableCreation-bytes/op 0 direct-TableCreation-mallocs
BenchmarkLuaDirectExecution/StringOperations-16 405411 2730 ns/op 0 direct-StringOperations-bytes/op 0 direct-StringOperations-mallocs
BenchmarkLuaBytecodeExecution/SimpleAddition-16 6323188 186.6 ns/op 219.73 MB/s 0 bytecode-SimpleAddition-bytes/op 0 bytecode-SimpleAddition-mallocs
BenchmarkLuaBytecodeExecution/LoopSum-16 162441 7137 ns/op 29.98 MB/s 0 bytecode-LoopSum-bytes/op 0 bytecode-LoopSum-mallocs
BenchmarkLuaBytecodeExecution/FunctionCall-16 175790 6386 ns/op 35.70 MB/s 0 bytecode-FunctionCall-bytes/op 0 bytecode-FunctionCall-mallocs
BenchmarkLuaBytecodeExecution/TableCreation-16 152374 7534 ns/op 29.47 MB/s 0 bytecode-TableCreation-bytes/op 0 bytecode-TableCreation-mallocs
BenchmarkLuaBytecodeExecution/StringOperations-16 705818 1548 ns/op 158.23 MB/s 0 bytecode-StringOperations-bytes/op 0 bytecode-StringOperations-mallocs
PASS
ok git.sharkk.net/Sky/LuaJIT-to-Go/bench 33.958s