原文链接: go wasm fib 对比原生js
下一篇: tinygo wasm 优化对比js原生
只能说进步空间很大...
也可能这种递归不是很适合这个场景
fib.go
package main
import (
"syscall/js"
)
func _fib(n int) int {
if n < 2 {
return n
}
return _fib(n-1) + _fib(n-2)
}
func fib(this js.Value, i []js.Value) interface{} {
return js.ValueOf(_fib(i[0].Int()))
}
func registerCallbacks() {
js.Global().Set("fib", js.FuncOf(fib))
}
func main() {
c := make(chan struct{}, 0)
println("WASM Go Initialized")
// register functions
registerCallbacks()
<-c
}
// set GOARCH=wasm
// set GOOS=js
// go build -o lib.wasm main.go
fib.html
<!DOCTYPE html>
<!--
Copyright 2018 The Go Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file.
-->
<html>
<head>
<meta charset="utf-8"/>
<title>Go wasm</title>
</head>
<body>
<script src="wasm_exec.js"></script>
<script>
if (!WebAssembly.instantiateStreaming) {
// polyfill
WebAssembly.instantiateStreaming = async (resp, importObject) => {
const source = await (await resp).arrayBuffer();
return await WebAssembly.instantiate(source, importObject);
};
}
const go = new Go();
let mod, inst;
WebAssembly.instantiateStreaming(fetch("./fib.wasm"), go.importObject).then(
async result => {
mod = result.module;
inst = result.instance;
await go.run(inst);
}
);
function fibJS(n) {
return n < 2 ? n : fibJS(n - 1) + fibJS(n - 2)
}
let size = 30
function testTime(f) {
let st = +new Date()
for (let i = 0; i <= size; i++)
f(i)
let ed = +new Date()
return ed - st
}
function test() {
for (let i = 0; i < 10; i++) {
let timeGo = testTime(fib)
let timeJS = testTime(fibJS)
console.log({
timeGo, timeJS
})
}
}
</script>
<button onclick="test()">test</button>
</body>
</html>
go闭包写法, 效果更差, 普通函数大概两倍, 闭包三倍
func fib(this js.Value, i []js.Value) interface{} { var _fib func(int) int _fib = func(n int) int { if n < 2 { return n } return _fib(n-1) + _fib(n-2) } return js.ValueOf(_fib(i[0].Int())) }