【问题标题】:Performance of v8 array creation in NodejsNodejs 中 v8 数组创建的性能
【发布时间】:2016-03-21 08:56:39
【问题描述】:

我正在尝试将 JS 算法移植到 C++,看看是否可以提高性能,但我在填充 v8 数组时面临巨大的性能瓶颈。

这是一个仅复制填充数组的 sn-p。我创建了一个包含 800k 个项目的数组,每个项目都是一个包含 17 个数字的数组。这个算法在我的机器上执行需要 3 秒,这是相当大的。

有没有办法加快速度?

#include <node.h>

namespace demo {

  using namespace v8; // just for lisibility of the example

  void Method(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    Local<Array> array = Array::New(isolate, 800000);

    for (int i = 0; i < 800000; ++i) {
      Local<Array> line = Array::New(isolate, 17);

      for (int j = 0; j < 17; ++j) {
        line->Set(j, Number::New(isolate, i * 100 + j));
      }

      array->Set(i, line);
    }

    args.GetReturnValue().Set(array);
  }

  void Init(Local<Object> exports) {
    NODE_SET_METHOD(exports, "hello", Method);
  }

  NODE_MODULE(parser, Init)

}

【问题讨论】:

  • 您是否将其与在 javascript 中创建相同的数组进行了比较?目前在 javascript 中创建一些东西并将它们传递给 C++ 会更快。
  • 确实如此,但真正的算法实际上是大数据的 CSV 解析器,因此在启动算法时数组长度是未知的。在这个示例中我实际上使用了一些快捷方式,因为实际上我无法将 array 变量预分配给已知大小。

标签: c++ node.js v8 node.js-addon


【解决方案1】:

从 C++ 创建 JS 对象(并与它们交互)比从 JS 中创建更昂贵。这可以轻松抵消其余 C++ 代码带来的性能提升。

您可以通过Buffer 进行通信来解决此问题(序列化开销通常会低于上述)。更重要的是,这还可以让您完成 v8 主线程之外的工作。

如果您只处理数字,使用Buffer.readIntLE(或类似方法)应该相对简单。您还可以将数组的长度编码到缓冲区的前几个字节中。以下是 JS 方面的情况:

var buf = new Buffer(/* Large enough to contain your serialized data. */);

// Function defined in your C++ addon.
addon.populate(buf, function (err) {
  if (err) {
    // Handle C++ error.
    return;
  }
  // At this point, `buf` contains the serialized data. Deserialization
  // will depend on the chosen serialization format but a reasonable
  // option could be the following:
  var arr = [];
  var pos = 4;
  var size = buf.readInt32LE(0);
  while (size--) {
    var subarr = new Array(17);
    for (var i = 0; i < 17; i++) {
      subarr[i] = buf.readInt32LE(pos);
      pos += 4;
    }
    arr.push(subarr);
  }
  // `arr` now contains your decoded data.
});

代码的 C++ 部分将保留对buf 数据的引用(char *)并将其填充到工作线程中(请参阅nanAsyncWorker 以获得方便的帮助)。

【讨论】:

  • 最好的数组根本不是数组,而是二进制数据流。好电话。
【解决方案2】:

正如 mtth 所说,在 C++ 中使用 JS 数组非常昂贵。使用缓冲区可以,但您也可以使用 TypedArrays。这些可以从 C++ 中作为指向连续、对齐的内存块的指针进行访问,这使得它们易于使用并且可以快速迭代。

有关如何访问其内容的一些信息,请参阅 https://stackoverflow.com/a/31712512/1218408

【讨论】:

    猜你喜欢
    • 2015-06-05
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 2022-07-18
    • 2019-08-23
    • 2012-01-15
    • 2016-01-11
    相关资源
    最近更新 更多