Node.jsGolang

NodejsI/OCPUC、C++、Rust、GolangWebAssembly
Node.jsGolangNode.jsGolang
ReactRust
Node.jsGolang

测试项

Node.js的GolangGolangwasmNode.js

速度与金钱

《The Good, the Bad and the Ugly》
在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第1张

Node.js(好人)

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第2张

优点:

I/Onpm

Golang(坏人)

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第3张

优点:

GoogleGolangCPU

nodejs-golang/WebAssembly(丑陋的人)

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第4张

优点:

JavaScriptJavaScript.wasm

最后这个测试项我们重点聊聊:

“js”“wasm”``(所有的和
GOOS=js GOARCH=wasm go build -o main.wasm
Gowasm_exec.jsglue code
${GOROOT}/misc/wasm/wasm_exec.js
@assemblyscript/loadernodejs-golang@assemblyscript/loaderJavaScriptwasm
require('./go/misc/wasm/wasm_exec');
const go = new Go();
...
const wasm = fs.readFileSync(wasmPath);
const wasmModule = await loader.instantiateStreaming(wasm, go.importObject);
go.run(wasmModule.instance);
.wasm
C: emcc hello.c -s WASM=1 -o code.html

C++: em++ hello.cpp -s WASM=1 -o code.html

Rust:cargo build --target wasm --release
在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第5张

让我们来看看谁是狂野西部最快的枪……

为此,我们需要创建 2 个服务器

1.Golang服务器

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第6张
package main

import (
    ...
    "fmt"
    ...
    "net/开发指南"
    ...
)

func main() {
    ...
    fmt.Print("Golang: Server is running at 开发指南://localhost:8090/")
    开发指南.ListenAndServe(":8090", nil)
}

2. Node.js 服务器

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第7张
const 开发指南 = require('开发指南');
...
(async () => {
  ...
  开发指南.createServer((req, res) => {
    ...
  })
  .listen(8080, () => {
    console.log('Nodejs: Server is running at 开发指南://localhost:8080/');
  });
})();

我们将测试每个任务的执行时间,注意:

GolangNode.jsWebAssembly

最后的决斗

1.“ping”请求

只是检查一下一个请求执行将花费多少时间

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第8张

Node.js

const nodejsPingHandler = (req, res) => {
  console.time('Nodejs: ping');

  const result = 'Pong';

  console.timeEnd('Nodejs: ping');

  res.statusCode = 200;
  res.setHeader('Content-Type', 'application/json');
  res.write(JSON.stringify({ result }));
  res.end();
};

Golang

// golang/ping.js

const 开发指南 = require('开发指南');

const golangPingHandler = (req, res) => {
  const options = {
    hostname: 'localhost',
    port: 8090,
    path: '/ping',
    method: 'GET',
  };

  let result = '';

  console.time('Golang: ping');

  const request = 开发指南.request(options, (response) => {
    response.on('data', (data) => {
      result += data;
    });
    response.on('end', () => {
      console.timeEnd('Golang: ping');

      res.statusCode = 200;
      res.setHeader('Content-Type', 'application/json');
      res.write(JSON.stringify({ result }));
      res.end();
    });
  });

  request.on('error', (error) => {
    console.error(error);
  });

  request.end();
};
// main.go

func ping(w 开发指南.ResponseWriter, req *开发指南.Request) {
    fmt.Fprintf(w, "Pong")
}

nodejs-golang

// nodejs-golang/ping.js

const nodejsGolangPingHandler = async (req, res) => {
  console.time('Nodejs-Golang: ping');

  const result = global.GolangPing();

  console.timeEnd('Nodejs-Golang: ping');

  res.statusCode = 200;
  res.setHeader('Content-Type', 'application/json');
  res.write(JSON.stringify({ result }));
  res.end();
};
// main.go

package main

import (
    "syscall/js"
)

func GolangPing(this js.Value, p []js.Value) interface{} {
    return js.ValueOf("Pong")
}

func main() {
    c := make(chan struct{}, 0)

    js.Global().Set("GolangPing", js.FuncOf(GolangPing))

    <-c
}

结果:

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第9张

两个数字的简单求和

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第10张

Node.js

const result = p1 + p2;

Golang

func sum(w 开发指南.ResponseWriter, req *开发指南.Request) {
    p1, _ := strconv.Atoi(req.URL.Query().Get("p1"))
    p2, _ := strconv.Atoi(req.URL.Query().Get("p2"))

    sum := p1 + p2

    fmt.Fprint(w, sum)
}

nodejs-golang

func GolangSum(this js.Value, p []js.Value) interface{} {
    sum := p[0].Int() + p[1].Int()
    return js.ValueOf(sum)
}

结果

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第11张

计算斐波那契数列(第 100000 个数)

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第12张

Node.js

const fibonacci = (num) => {
  let a = BigInt(1),
    b = BigInt(0),
    temp;

  while (num > 0) {
    temp = a;
    a = a + b;
    b = temp;
    num--;
  }

  return b;
};

Golang

func fibonacci(w 开发指南.ResponseWriter, req *开发指南.Request) {
    nValue, _ := strconv.Atoi(req.URL.Query().Get("n"))

    var n = uint(nValue)

    if n <= 1 {
        fmt.Fprint(w, big.NewInt(int64(n)))
    }

    var n2, n1 = big.NewInt(0), big.NewInt(1)

    for i := uint(1); i < n; i++ {
        n2.Add(n2, n1)
        n1, n2 = n2, n1
    }

    fmt.Fprint(w, n1)
}

nodejs-golang

func GolangFibonacci(this js.Value, p []js.Value) interface{} {
    var n = uint(p[0].Int())

    if n <= 1 {
        return big.NewInt(int64(n))
    }

    var n2, n1 = big.NewInt(0), big.NewInt(1)

    for i := uint(1); i < n; i++ {
        n2.Add(n2, n1)
        n1, n2 = n2, n1
    }

    return js.ValueOf(n1.String())
}

结果

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第13张

计算 md5(10k 字符串)

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第14张

Node.js


const crypto = require('crypto');

const md5 = (num) => {
  for (let i = 0; i < num; i++) {
    crypto.createHash('md5').update('nodejs-golang').digest('hex');
  }
  return num;
};

Golang

func md5Worker(c chan string, wg *sync.WaitGroup) {
    hash := md5.Sum([]byte("nodejs-golang"))

    c <- hex.EncodeToString(hash[:])

    wg.Done()
}

func md5Array(w 开发指南.ResponseWriter, req *开发指南.Request) {
    n, _ := strconv.Atoi(req.URL.Query().Get("n"))

    c := make(chan string, n)
    var wg sync.WaitGroup

    for i := 0; i < n; i++ {
        wg.Add(1)
        go md5Worker(c, &wg)
    }

    wg.Wait()

    fmt.Fprint(w, n)
}

nodejs-golang

func md5Worker(c chan string, wg *sync.WaitGroup) {
    hash := md5.Sum([]byte("nodejs-golang"))

    c <- hex.EncodeToString(hash[:])

    wg.Done()
}

func GolangMd5(this js.Value, p []js.Value) interface{} {
    n := p[0].Int()

    c := make(chan string, n)
    var wg sync.WaitGroup

    for i := 0; i < n; i++ {
        wg.Add(1)
        go md5Worker(c, &wg)
    }

    wg.Wait()

    return js.ValueOf(n)
}

结果

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第15张

计算 sha256(10k 字符串)

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第16张

Node.js


const crypto = require('crypto');

const sha256 = (num) => {
  for (let i = 0; i < num; i++) {
    crypto.createHash('sha256').update('nodejs-golang').digest('hex');
  }
  return num;
};

Golang

func sha256Worker(c chan string, wg *sync.WaitGroup) {
    h := sha256.New()
    h.Write([]byte("nodejs-golang"))
    sha256_hash := hex.EncodeToString(h.Sum(nil))

    c <- sha256_hash

    wg.Done()
}

func sha256Array(w 开发指南.ResponseWriter, req *开发指南.Request) {
    n, _ := strconv.Atoi(req.URL.Query().Get("n"))

    c := make(chan string, n)
    var wg sync.WaitGroup

    for i := 0; i < n; i++ {
        wg.Add(1)
        go sha256Worker(c, &wg)
    }

    wg.Wait()

    fmt.Fprint(w, n)
}

nodejs-golang

func sha256Worker(c chan string, wg *sync.WaitGroup) {
    h := sha256.New()
    h.Write([]byte("nodejs-golang"))
    sha256_hash := hex.EncodeToString(h.Sum(nil))

    c <- sha256_hash

    wg.Done()
}

func GolangSha256(this js.Value, p []js.Value) interface{} {
    n := p[0].Int()

    c := make(chan string, n)
    var wg sync.WaitGroup

    for i := 0; i < n; i++ {
        wg.Add(1)
        go sha256Worker(c, &wg)
    }

    wg.Wait()

    return js.ValueOf(n)
}

结果

在 Node.js 中引入 Golang ,会让它更快吗? (http://www.ztxapp.com/) 热门资讯 第17张

最终结果

Node.jsGolangWebAssemblynodejs-golangGolangwasmJavaScriptNode.jsGolangJavaScriptWebAssembly

结论

快是好的,但准确才是一切。- Wyatt Earp

Node.jsCPUNode.jsCPUNode.jsWebAssemblyWasmJS

“一个优秀的架构师会假装还没有做出决定,并对系统进行反复的测试和优化,以便这些决定仍然可以尽可能长时间地推迟或更改。优秀的架构师会将未做决策的数量最大化。” - Robert C. Martin 的 Clean Architecture