为什么asm.js比普通的js(质数生成)要慢?如何加快速度?

这里是素数生成算法,一个带有“ use 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,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,')}</i>`);

function write(text){
  document.body.innerHTML += text;
}
<h2>First 4048 prime numbers js vs asm.js</h2>

Jackiezhan115 回答:为什么asm.js比普通的js(质数生成)要慢?如何加快速度?

问题是您正在“微基准测试”,即您正在尝试评估非常小的算法或一段代码的性能。这会导致以下问题

  • 您可能会遇到计时器准确性问题
  • 您的测量结果可能会花费大量时间在测试线束或设置代码中
  • 您将只评估基础语言功能的一小部分
  • 由于每种方法的优化器存在差异,因此您的测量结果将有很大的偏差
  • 您的测量结果可能会因运行时优化代码所花费的迭代次数而有所偏差。

基本上,由于仅有一个简单的微基准,您无法成功评估语言之间的性能差异。这就是为什么行业标准基准测试倾向于衡量一整套更复杂的算法的原因。

本文链接:https://www.f2er.com/3051878.html

大家都在问