Joe*_*ani 12 javascript c++ performance node.js
我一直在尝试使用Node.JS和C++插件,发现在使用C++插件时填充Int32Array要慢得多,而不是在Node.JS/JavaScript中直接填充.
Node.JS:133~ms
C++:1103~ms
有人知道为什么吗?我的测试代码包含了相当大阵,并为包含循环如果语句.
我怀疑我在C++插件中错误地填充了数组.(?)
JavaScript的:
var testArray = new Int32Array(36594368);
var i = 0;
for (var xi = 0; xi < 332; xi++) {
    for (var yi = 0; yi < 332; yi++) {
        for (var zi = 0; zi < 332; zi++) {
            if ((xi + yi + zi) % 62 == 0) testArray[i] = 2;
            else if (yi < 16) testArray[i] = 2;
            else if (yi == 16) testArray[i] = 1;
            else testArray[i] = 0;
            i++;
        }
    }
}
C++插件:
Local<Int32Array> testArray = Int32Array::New(ArrayBuffer::New(isolate, 4 * 36594368), 0, 36594368);
int i = 0;
for (int xi = 0; xi < 332; xi++) {
    for (int yi = 0; yi < 332; yi++) {
        for (int zi = 0; zi < 332; zi++) {
            if ((xi + yi + zi) % 62 == 0) testArray->Set(i, Integer::New(isolate, 2));
            else if (yi < 16) testArray->Set(i, Integer::New(isolate, 2));
            else if (yi == 16) testArray->Set(i, Integer::New(isolate, 1));
            else testArray->Set(i, Integer::New(isolate, 0));
            i++;
        }
    }
}
编辑:只是添加,我在我的C++代码中使用的函数是V8函数,并不是我自己定义的.有没有其他方法在Int32Array中设置值而不使用它们?
waT*_*eim 10
我并不感到惊讶,这写得很慢,但你可以做很多事情来加速它.关键的见解是,当在节点中处理JavaScript类型的数组时,您可以访问内存缓冲区并直接对其进行操作.
虽然在处理普通的JavaScript数组/对象时,以下是必要的
整数::新(隔离,值)
和
testArray-> Set(value)
例如,以下行
testArray->Set(i, Integer::New(isolate, 0));
创建一个新的Number对象,将整数0转换为double,因为所有JavaScript数都是double,调用Set使用Number对象,然后将double转换回整数,因为它将值存储在Int32类型的数组中,然后破坏数字对象.这发生了300万次.
但是类型化数组是不同的,并且调用GetIndexedPropertiesExternalArrayData提供对底层缓冲区的一个访问,对于Int32Array,它是int的缓冲区.这允许重写C++函数以避免所有这些分配和强制转换:
void doMkArray(const FunctionCallbackInfo<Value> &args)
{
   v8::Isolate *I = v8::Isolate::GetCurrent();
   Local<Int32Array> testArray = Int32Array::New(ArrayBuffer::New(I, 4 * 36594368),0,36594368);
   int *dptr = (int*)testArray->GetIndexedPropertiesExternalArrayData();
   int i = 0;
   for (int xi = 0; xi < 332; xi++)
   {
      for (int yi = 0; yi < 332; yi++)
      {
         for (int zi = 0; zi < 332; zi++)
         {
            if ((xi + yi + zi) % 62 == 0) dptr[i] = 2;
            else if (yi < 16) dptr[i] = 2;
            else if (yi == 16) dptr[i] = 1;
            else dptr[i] = 0;
            i++;
         }
      }
   }
   args.GetReturnValue().Set(testArray);
}
用上面的代替可以让事情变得更快,但是测试需要多快.在下面的包可以被克隆和运行时(使用节点0.12.5)结果示于下述
  Performance Tests
    ? via javascript (169ms)
    ? via c++ (141ms)
所以单独使用C++会更快,但也许并不是那么令人惊奇,但是如果Javascript和C++循环(参见src)都被注释掉了,并且只包含了数组分配:
    void doMkArray(const FunctionCallbackInfo<Value> &args)
    {
       v8::Isolate *I = v8::Isolate::GetCurrent();
       Local<Int32Array> testArray = Int32Array::New(ArrayBuffer::New(I, 4 
/*
...
然后时间变为
  Performance Tests
    ? via javascript (62ms)
    ? via c++ (80ms)
换句话说,简单地分配数组在JavaScript中大约需要60ms,在C++模块中需要80ms.但这意味着剩下的时间是在循环中花费的时间,在C++中约为60ms,在Javascript中约为110ms.因此,对于主要使用直接缓冲区访问进行循环和计算的操作,首选C++.
| 归档时间: | 
 | 
| 查看次数: | 2982 次 | 
| 最近记录: |