你正在使用哪个版本的Go( go version
)?
$ go version
go version go1.20.3 darwin/amd64
这个问题在最新版本中是否会重现?
是的
你正在使用什么操作系统和处理器架构( go env
)?
go env
输出
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/penghaoh/.cache/go-build"
GOENV="/Users/penghaoh/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/penghaoh/Workplace/my_go_workspace/pkg/mod"
GONOPROXY="*"
GONOSUMDB="*"
GOOS="darwin"
GOPATH="/Users/penghaoh/Workplace/my_go_workspace"
GOPRIVATE="*"
GOPROXY="direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.20.3"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/h0/6tx4n9fn59z1vj88py9mncmr00vbmk/T/go-build2636679718=/tmp/go-build -gno-record-gcc-switches -fno-common"
你做了什么?
- 尝试用Go编写一个项目,重用一些逻辑
main.go
var done chan bool
func init() {
done = make(chan bool)
}
func main() {
var hash js.Func
hash = js.FuncOf(func(this js.Value, args []js.Value) any {
h := crypto.SHA512.New()
h.Write([]byte(args[0].String()))
return hex.EncodeToString(h.Sum(nil))
})
js.Global().Set("wasmHash", hash)
var close js.Func
close = js.FuncOf(func(this js.Value, args []js.Value) any {
defer close.Release()
defer hash.Release()
done <- true
return nil
})
js.Global().Set("close", close)
<-done
}
- 用
GOOS=js GOARCH=wasm go build -o wasm.wasm main.go
构建它,二进制文件大小为19.4 MB(我添加了一些额外的依赖项来模拟这个原型的实际项目) - 压缩wasm文件
gzip -9 -v -c wasm.wasm > wasm.wasm.gz
- 用
node ./main.js
运行它
main.js
const pako = require("pako");
require("./wasm_exec");
fs = require("fs");
const wasmBuffer = new Uint8Array(pako.ungzip(fs.readFileSync("wasm.wasm.gz")));
const go = new Go();
go.env = Object.assign({ TMPDIR: require("os").tmpdir() }, process.env);
go.exit = process.exit;
WebAssembly.instantiate(wasmBuffer, go.importObject).then((wasmModule) => {
go.run(wasmModule.instance);
console.log(wasmHash("asdf"));
close();
process.on("exit", (code) => {
// Node.js exits if no event handler is pending
// commend the block avoid deadlock
if (code === 0 && !go.exited) {
// deadlock, make Go print error and stack traces
go._pendingEvent = { id: 0 };
go._resume();
}
process.exit();
});
return;
});
你期望看到什么?
显示 asdf
的哈希结果。
你看到了什么?
如果二进制文件很大,在我看到结果后,我的机器上需要5秒钟才能退出。然而,令我惊讶的是,如果我用deno重写js文件,它在打印结果后立即退出。deno.js
import * as _ from "./wasm_exec.js";
const go = new window.Go();
const f = await Deno.open("./wasm.wasm");
const buf = await Deno.readAll(f);
const inst = await WebAssembly.instantiate(buf, go.importObject);
go.run(inst.instance);
const result = wasmHash("asdf");
console.log(result);
3条答案
按热度按时间bbuxkriu1#
这听起来更像是Node.js比Deno慢的问题,但也许我们可以在这里做些什么?
cc @golang/wasm
f4t66c6m2#
我不觉得这是性能差异,因为使用Nodejs的实际结果显示得很快。在调用所有go func之后,只是出现了奇怪的挂起。即使我明确地调用
process.exit(0)
,并且调用栈为空,它也无法正常工作。rseugnpd3#
这可能是Node.js中未修复的以下错误:nodejs/node#36616。如果你真的想解决这个问题,可以尝试一种可怕的方法来绕过它:nodejs/node#36616(评论)。