簡體   English   中英

填充Int32Array時,Node.JS性能與本機C ++插件相比

[英]Node.JS performance vs native C++ addon when populating an Int32Array

我一直在嘗試使用Node.JS和C ++插件,發現在使用C ++插件時填充Int32Array要慢得多,而不是在Node.JS / JavaScript中直接填充。

Node.JS:133~ms
C ++:1103~ms

有人知道為什么嗎? 我的測試代碼包含了相當大陣if語句循環。

我懷疑我在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中設置值而不使用它們?

使用C ++最大化Typed Array性能

我並不感到驚訝,這寫得很慢,但你可以做很多事情來加速它。 關鍵的見解是,當在節點中處理JavaScript類型的數組時,您可以訪問內存緩沖區並直接對其進行操作。

緩慢的主要來源

雖然在處理普通的JavaScript數組/對象時,以下是必要的

整數::新( 隔離

testArray-> Set( value

例如,以下行

testArray->Set(i, Integer::New(isolate, 0));

創建一個新的Number對象,將整數0轉換為double,因為所有JavaScript數都是double,使用Number對象調用Set ,然后將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 ++。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM