github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/cmd/wasm/benchmark.go (about) 1 package main 2 3 import ( 4 "github.com/PlatONnetwork/PlatON-Go/common" 5 "github.com/PlatONnetwork/PlatON-Go/core/lru" 6 "github.com/PlatONnetwork/PlatON-Go/life/exec" 7 "bytes" 8 "errors" 9 "fmt" 10 "github.com/syndtr/goleveldb/leveldb" 11 "gopkg.in/urfave/cli.v1" 12 "io/ioutil" 13 "os" 14 "runtime/pprof" 15 "time" 16 ) 17 18 // The runner used in the unit test is mainly responsible for testing the Platonlib c++ library. 19 // According to the wasm file in the dir scan directory, the wasm is accessed from the main entry. 20 // The db is created according to --outdir. The test tool judges the test result based on the log information. 21 22 var ( 23 wasmFileFlag = cli.StringFlag{ 24 Name: "file", 25 Usage: "wasm file", 26 } 27 28 loopFlag = cli.IntFlag{ 29 Name: "loop", 30 Usage: "execute count", 31 Value: 1, 32 } 33 34 profFlag = cli.StringFlag{ 35 Name: "prof", 36 Usage: "write cpuprofie to file", 37 } 38 ) 39 40 var benchmarkCommand = cli.Command{ 41 Action: benchmarkCmd, 42 Name: "benchmark", 43 Usage: "benchmark wasm vm", 44 ArgsUsage: "<dir>", 45 Flags: []cli.Flag{ 46 wasmFileFlag, 47 outDirFlag, 48 loopFlag, 49 profFlag, 50 }, 51 HideHelp: false, 52 } 53 54 func benchmarkCmd(ctx *cli.Context) error { 55 wasmFile := ctx.String(wasmFileFlag.Name) 56 outDir := ctx.String(outDirFlag.Name) 57 loop := ctx.Int(loopFlag.Name) 58 profFile := ctx.String(profFlag.Name) 59 60 if profFile != "" { 61 f, err := os.Create(profFile) 62 if err != nil { 63 return err 64 } 65 66 pprof.StartCPUProfile(f) 67 defer pprof.StopCPUProfile() 68 } 69 70 start := time.Now() 71 72 err := benchmark(wasmFile, outDir, loop) 73 74 if err != nil { 75 return err 76 } 77 78 end := time.Now() 79 80 fmt.Println("execute time:", end.Sub(start).String(), "loop:", loop) 81 82 return nil 83 } 84 func benchmark(wasmFile string, outDir string, loop int) error { 85 dbPath := outDir + testDBName 86 logStream := bytes.NewBuffer(make([]byte, 65535)) 87 os.RemoveAll(dbPath) 88 db, err := leveldb.OpenFile(dbPath, nil) 89 if err != nil { 90 return errors.New(fmt.Sprintf("open leveldb %s failed :%v", dbPath, err)) 91 } 92 code, err := ioutil.ReadFile(wasmFile) 93 if err != nil { 94 return err 95 } 96 97 m, functionCode, err := exec.ParseModuleAndFunc(code, nil) 98 99 if err != nil { 100 return err 101 } 102 103 if err := lru.SetWasmDB(outDir); err != nil { 104 return err 105 } 106 107 addr := common.HexToAddress("0x43355c787c50b647c425f594b441d4bd751951c1") 108 lru.WasmCache().Add(addr, &lru.WasmModule{m, functionCode}) 109 110 for i := 0; i < loop; i++ { 111 m, ok := lru.WasmCache().Get(addr) 112 if !ok { 113 return errors.New("get wasm cache error") 114 } 115 if err := runModule(m.Module, m.FunctionCode, db, logStream); err != nil { 116 return err 117 } 118 //lru.WasmCache().Purge() 119 } 120 db.Close() 121 return nil 122 }