github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/iextengine/wazero/impl_benchmark_test.go (about) 1 /* 2 - Copyright (c) 2023-present unTill Software Development Group B.V. 3 @author Michael Saigachenko 4 */ 5 6 package iextenginewazero 7 8 import ( 9 "context" 10 "testing" 11 12 "github.com/voedger/voedger/pkg/appdef" 13 "github.com/voedger/voedger/pkg/iextengine" 14 ) 15 16 func bench_purecall(b *testing.B) { 17 ctx := context.Background() 18 const simple = "simple" 19 moduleUrl := testModuleURL("./_testdata/allocs/pkg.wasm") 20 ee, err := testFactoryHelper(ctx, moduleUrl, []string{simple}, iextengine.ExtEngineConfig{MemoryLimitPages: 0xffff}, false) 21 if err != nil { 22 panic(err) 23 } 24 //ee.SetLimits(limits) 25 26 b.ResetTimer() 27 for n := 0; n < b.N; n++ { 28 if e := ee.Invoke(context.Background(), appdef.NewFullQName("test", simple), extIO); e != nil { 29 panic(e) 30 } 31 } 32 b.StopTimer() 33 ee.Close(ctx) 34 } 35 36 func bench_gc(b *testing.B, cycles int) { 37 38 const arrAppend = "arrAppend" 39 const arrReset = "arrReset" 40 ctx := context.Background() 41 moduleUrl := testModuleURL("./_testdata/allocs/pkggc.wasm") 42 ee, err := testFactoryHelper(ctx, moduleUrl, []string{arrAppend, arrReset}, iextengine.ExtEngineConfig{MemoryLimitPages: 0xffff}, false) 43 if err != nil { 44 panic(err) 45 } 46 //ee.SetLimits(limits) 47 48 b.ResetTimer() 49 for n := 0; n < b.N; n++ { 50 b.StopTimer() 51 for i := 0; i < cycles; i++ { 52 if e := ee.Invoke(context.Background(), appdef.NewFullQName("test", arrAppend), extIO); e != nil { 53 panic(e) 54 } 55 } 56 if e := ee.Invoke(context.Background(), appdef.NewFullQName("test", arrReset), extIO); e != nil { 57 panic(e) 58 } 59 b.StartTimer() 60 if e := ee.(*wazeroExtEngine).gc(testPkg, ctx); e != nil { 61 panic(e) 62 } 63 } 64 65 b.StopTimer() 66 ee.Close(ctx) 67 68 } 69 70 /* 71 goos: linux 72 goarch: amd64 73 cpu: 12th Gen Intel(R) Core(TM) i7-12700 74 Benchmark_GarbageCollection/simple-call-no-gc-20 12560898 82.73 ns/op 0 B/op 0 allocs/op 75 Benchmark_GarbageCollection/gc-after-no-allocs-20 24 47296163 ns/op 888 B/op 12 allocs/op 76 Benchmark_GarbageCollection/gc-after-6-allocs-48b-20 25 47137050 ns/op 888 B/op 12 allocs/op 77 Benchmark_GarbageCollection/gc-after-20000-allocs-20 24 46626752 ns/op 888 B/op 12 allocs/op 78 */ 79 func Benchmark_GarbageCollection(b *testing.B) { 80 b.Run("simple-call-no-gc", func(b *testing.B) { 81 bench_purecall(b) 82 }) 83 b.Run("gc-after-no-allocs", func(b *testing.B) { 84 bench_gc(b, 0) 85 }) 86 b.Run("gc-after-6-allocs-48b", func(b *testing.B) { 87 bench_gc(b, 3) 88 }) 89 b.Run("gc-after-20000-allocs", func(b *testing.B) { 90 bench_gc(b, 10000) 91 }) 92 } 93 94 func bench_extensions(b *testing.B, gc bool, compile bool) { 95 96 funcs := []string{"oneGetOneIntent5calls", "oneGetNoIntents2calls", "oneGetLongStr3calls", "oneKey1call", "doNothing"} 97 98 ctx := context.Background() 99 wsm := "./_testdata/benchmarks/pkg.wasm" 100 if gc { 101 wsm = "./_testdata/benchmarks/pkggc.wasm" 102 } 103 moduleUrl := testModuleURL(wsm) 104 ee, err := testFactoryHelper(ctx, moduleUrl, funcs, iextengine.ExtEngineConfig{MemoryLimitPages: 0xffff}, compile) 105 if err != nil { 106 panic(err) 107 } 108 defer ee.Close(ctx) 109 for _, extname := range funcs { 110 ext := appdef.NewFullQName(testPkg, extname) 111 b.Run(extname, func(b *testing.B) { 112 b.ResetTimer() 113 for i := 0; i < b.N; i++ { 114 err := ee.Invoke(context.Background(), ext, extIO) 115 if err != nil { 116 panic(err) 117 } 118 } 119 }) 120 } 121 } 122 123 /* 124 goos: linux 125 goarch: amd64 126 cpu: 12th Gen Intel(R) Core(TM) i7-12700 127 Benchmark_Extensions_NoGc/Compiler/oneGetOneIntent5calls-20 307974 5875 ns/op 2988 B/op 55 allocs/op 128 Benchmark_Extensions_NoGc/Compiler/oneGetNoIntents2calls-20 728787 2519 ns/op 1728 B/op 26 allocs/op 129 Benchmark_Extensions_NoGc/Compiler/oneGetLongStr3calls-20 90838 48478 ns/op 133032 B/op 33 allocs/op 130 Benchmark_Extensions_NoGc/Compiler/oneKey1call-20 1000000 1449 ns/op 640 B/op 15 allocs/op 131 Benchmark_Extensions_NoGc/Compiler/doNothing-20 3906926 303.5 ns/op 160 B/op 3 allocs/op 132 Benchmark_Extensions_NoGc/Interpreter/oneGetOneIntent5calls-20 267399 5619 ns/op 3156 B/op 61 allocs/op 133 Benchmark_Extensions_NoGc/Interpreter/oneGetNoIntents2calls-20 628476 2079 ns/op 1800 B/op 29 allocs/op 134 Benchmark_Extensions_NoGc/Interpreter/oneGetLongStr3calls-20 31657 43928 ns/op 133128 B/op 37 allocs/op 135 Benchmark_Extensions_NoGc/Interpreter/oneKey1call-20 924883 1109 ns/op 688 B/op 17 allocs/op 136 Benchmark_Extensions_NoGc/Interpreter/doNothing-20 3429517 327.5 ns/op 184 B/op 4 allocs/op 137 */ 138 func Benchmark_Extensions_NoGc(b *testing.B) { 139 b.Run("Compiler", func(b *testing.B) { 140 bench_extensions(b, false, true) 141 }) 142 b.Run("Interpreter", func(b *testing.B) { 143 bench_extensions(b, false, false) 144 }) 145 } 146 func Skip_Benchmark_Extensions_WithGc(b *testing.B) { 147 bench_extensions(b, true, true) 148 } 149 150 func benchmarkRecover(b *testing.B, limitPages uint, expectedRuns int) { 151 const arrAppend2 = "arrAppend2" 152 ctx := context.Background() 153 moduleUrl := testModuleURL("./_testdata/allocs/pkg.wasm") 154 ee, err := testFactoryHelper(ctx, moduleUrl, []string{arrAppend2}, iextengine.ExtEngineConfig{MemoryLimitPages: limitPages}, true) 155 if err != nil { 156 panic(err) 157 } 158 defer ee.Close(ctx) 159 160 we := ee.(*wazeroExtEngine) 161 we.autoRecover = false 162 163 ext := appdef.NewFullQName(testPkg, arrAppend2) 164 for runs := 0; runs < expectedRuns; runs++ { 165 if err := ee.Invoke(context.Background(), ext, extIO); err != nil { 166 panic(err) 167 } 168 } 169 170 //we.backupMemory() 171 172 // the next call should fail 173 if err := ee.Invoke(context.Background(), ext, extIO); err == nil { 174 panic("err expected") 175 } 176 177 b.ResetTimer() 178 for i := 0; i < b.N; i++ { 179 we.recover(context.Background()) 180 } 181 } 182 183 func benchmarkRecoverClean(b *testing.B, limitPages uint) { 184 ctx := context.Background() 185 moduleUrl := testModuleURL("./_testdata/allocs/pkg.wasm") 186 ee, err := testFactoryHelper(ctx, moduleUrl, []string{}, iextengine.ExtEngineConfig{MemoryLimitPages: limitPages}, true) 187 if err != nil { 188 panic(err) 189 } 190 defer ee.Close(ctx) 191 we := ee.(*wazeroExtEngine) 192 err = we.selectModule(testPkg) 193 if err != nil { 194 panic(err) 195 } 196 b.ResetTimer() 197 for i := 0; i < b.N; i++ { 198 we.recover(context.Background()) 199 } 200 } 201 202 /* 203 goos: linux 204 goarch: amd64 205 cpu: 12th Gen Intel(R) Core(TM) i7-12700 206 Benchmark_Recover/2Mib-1%-20 6808 168937 ns/op 2221915 B/op 61 allocs/op 207 Benchmark_Recover/2Mib-50%-20 6200 178177 ns/op 2221917 B/op 61 allocs/op 208 Benchmark_Recover/2Mib-100%-20 6007 191219 ns/op 2233567 B/op 63 allocs/op 209 Benchmark_Recover/8Mib-100%-20 1484 759637 ns/op 8525009 B/op 63 allocs/op 210 Benchmark_Recover/100Mib-70%-20 117 9026536 ns/op 100078791 B/op 63 allocs/op 211 */ 212 func Benchmark_Recover(b *testing.B) { 213 WasmPreallocatedBufferSize = 20000 214 b.Run("2Mib-1%", func(b *testing.B) { benchmarkRecoverClean(b, 0x20) }) 215 WasmPreallocatedBufferSize = 1000000 216 b.Run("2Mib-50%", func(b *testing.B) { benchmarkRecoverClean(b, 0x20) }) 217 b.Run("2Mib-100%", func(b *testing.B) { benchmarkRecover(b, 0x20, 3) }) 218 b.Run("8Mib-100%", func(b *testing.B) { benchmarkRecover(b, 0x80, 26) }) 219 b.Run("100Mib-70%", func(b *testing.B) { benchmarkRecover(b, 0x5f5, 209) }) 220 } 221 222 func Benchmark_ArrayCopy(b *testing.B) { 223 const backupSize = 2000000 224 const heapSize = 10000000 225 backup := make([]byte, backupSize) 226 heap := make([]byte, heapSize) 227 _ = append(heap, 1) 228 b.Run("recommended", func(b *testing.B) { 229 b.ResetTimer() 230 for i := 0; i < b.N; i++ { 231 //_ = append(heap[0:0], backup...) 232 heap = make([]byte, len(backup)) 233 copy(heap, backup) 234 b.StopTimer() 235 heap = make([]byte, heapSize) 236 _ = append(heap, 1) 237 b.StartTimer() 238 } 239 }) 240 b.Run("shrink", func(b *testing.B) { 241 b.ResetTimer() 242 for i := 0; i < b.N; i++ { 243 heap = heap[0:len(backup)] 244 copy(heap[0:len(backup)], backup[0:]) 245 b.StopTimer() 246 heap = make([]byte, heapSize) 247 _ = append(heap, 1) 248 b.StartTimer() 249 } 250 }) 251 252 }