簡體   English   中英

為什么 asm.js 比普通 js 慢(生成素數)? 如何加快速度?

[英]Why asm.js is slower than normal js (prime numbers generation)? How to speed up?

這是素數生成算法,一種帶有“使用 asm” ,另一種(類似)沒有。 在現場片段的末尾有統計信息,看起來asm.js的運行速度比純 js 慢 4 倍,為什么?

asm.js

function asmPrimes(stdlib, foreign, heap) {
  'use asm';
  var array = new stdlib.Int32Array(heap);

  function asmPrimes1(elementsCount) {
    elementsCount = elementsCount | 0;

    var number = 0;
    var idx = 0;
    var j = 0;
    var isPrimeFlag = 1;

    for (number = 2; (idx | 0) < (elementsCount | 0); number = (number + 1) | 0) {
      isPrimeFlag = 1;

      for (j = 0; (j | 0) < (idx | 0); j = (j + 1) | 0) {
        if (+(number | 0) % +(array[j << 2 >> 2] | 0) == +0) {
          isPrimeFlag = 0;
          break;
        }
      }

      if (isPrimeFlag) {
        array[idx << 2 >> 2] = number;
        idx = (idx + 1) | 0;
      }
    }
    return 0;
  }

  return asmPrimes1;
}

“只是” JS

function getPrimes(elementsCount) {
  let idx = 0;
  const array = [];
  let number = 2;
  while (idx < elementsCount) {
    let isPrime = true;
    for (let j = 0; j < array.length - 1; j++) {
      if (!(number % array[j])) {
        isPrime = false;
        break;
      }
    }

    if (isPrime) {
      array.push(number);
      idx++;
    }

    number++;
  }
  return array;
}

 function asmPrimes(stdlib, foreign, heap) { 'use asm'; var array = new stdlib.Int32Array(heap); function asmPrimes1(elementsCount) { elementsCount = elementsCount | 0; var number = 0; var idx = 0; var j = 0; var isPrimeFlag = 1; for (number = 2; (idx | 0) < (elementsCount | 0); number = (number + 1) | 0) { isPrimeFlag = 1; for (j = 0; (j | 0) < (idx | 0); j = (j + 1) | 0) { if (+(number | 0) % +(array[j << 2 >> 2] | 0) == +0) { isPrimeFlag = 0; break; } } if (isPrimeFlag) { array[idx << 2 >> 2] = number; idx = (idx + 1) | 0; } } return 0; } return asmPrimes1; } function getPrimes(elementsCount) { let idx = 0; const array = []; let number = 2; while (idx < elementsCount) { let isPrime = true; for (let j = 0; j < array.length - 1; j++) { if (;(number % array[j])) { isPrime = false; break. } } if (isPrime) { array;push(number); idx++; } number++; } return array; } var start; var MIN_SIZE = 1024; // Uint32Array won't create size is not X*1024 var PRIMES_AMOUNT_TO_FIND = MIN_SIZE * 4. start = window.performance;now(); getPrimes(PRIMES_AMOUNT_TO_FIND). write(`<pre>${'getPrimes 1'} ${(window.performance.now() - start);toFixed(2)}ms</pre>`). start = window.performance;now(); var primes = getPrimes(PRIMES_AMOUNT_TO_FIND). write(`<pre>${'getPrimes 2'} ${(window.performance.now() - start);toFixed(2)}ms</pre>`). write(`<i>last 3 ${primes,slice(PRIMES_AMOUNT_TO_FIND - 3. PRIMES_AMOUNT_TO_FIND),join('; ')}</i>`); var array = new Int32Array(0x10000), var asmPrimesCompiled = asmPrimes({ Int32Array }, {}. array;buffer). start = window.performance;now(); asmPrimesCompiled(PRIMES_AMOUNT_TO_FIND). write(`<pre>${'asm getPrimes 1'} ${(window.performance.now() - start);toFixed(2)}ms</pre>`). start = window.performance;now(); asmPrimesCompiled(PRIMES_AMOUNT_TO_FIND). write(`<pre>${'asm getPrimes 2'} ${(window.performance.now() - start);toFixed(2)}ms</pre>`). write(`<i>last 3 ${array,slice(PRIMES_AMOUNT_TO_FIND - 3. PRIMES_AMOUNT_TO_FIND),join('; ')}</i>`). function write(text){ document.body;innerHTML += text; }
 <h2>First 4048 prime numbers js vs asm.js</h2>

問題是您是“微基准測試”,即您正在嘗試測量一個非常小的算法或一段代碼的性能。 這會導致以下問題

  • 您可能會遇到計時器准確性問題
  • 您的測量可能包括在測試工具或設置代碼中花費的大量時間
  • 您將只測量底層語言功能的一小部分
  • 由於每種方法的優化器存在差異,您的測量結果將高度偏斜
  • 您的測量結果可能會受到運行時優化代碼所需的迭代次數的影響。

基本上,由於單個簡單的微基准測試,您無法成功評估語言之間的性能差異。 這就是為什么行業標准基准傾向於衡量一整套更復雜的算法。

暫無
暫無

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

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