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++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
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++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:只是添加,我在我的C++代码中使用的函数是V8函数,并不是我自己定义的.有没有其他方法在Int32Array中设置值而不使用它们?
waT*_*eim 10
我并不感到惊讶,这写得很慢,但你可以做很多事情来加速它.关键的见解是,当在节点中处理JavaScript类型的数组时,您可以访问内存缓冲区并直接对其进行操作.
虽然在处理普通的JavaScript数组/对象时,以下是必要的
整数::新(隔离,值)
和
testArray-> Set(value)
例如,以下行
testArray->Set(i, Integer::New(isolate, 0));
Run Code Online (Sandbox Code Playgroud)
创建一个新的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);
}
Run Code Online (Sandbox Code Playgroud)
用上面的代替可以让事情变得更快,但是测试需要多快.在下面的包可以被克隆和运行时(使用节点0.12.5)结果示于下述
Performance Tests
? via javascript (169ms)
? via c++ (141ms)
Run Code Online (Sandbox Code Playgroud)
所以单独使用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
/*
...
Run Code Online (Sandbox Code Playgroud)
然后时间变为
Performance Tests
? via javascript (62ms)
? via c++ (80ms)
Run Code Online (Sandbox Code Playgroud)
换句话说,简单地分配数组在JavaScript中大约需要60ms,在C++模块中需要80ms.但这意味着剩下的时间是在循环中花费的时间,在C++中约为60ms,在Javascript中约为110ms.因此,对于主要使用直接缓冲区访问进行循环和计算的操作,首选C++.