Подтвердить что ты не робот

Почему куб быстрее, чем квадрат

Я написал это:

  var max = 0xffffff * 4;
  var step = 1 / max;
  function cube() {
    var result = 0.;
    for (var x = 0.; x < 1; x += step) {
      result += x * x * x;
    }
    return result;
  }
  function mul() {
    var result = 0.;
    for (var x = 0.; x < 1; x += step) {
      result += x * x;
    }
    return result;
  }
  function go() {
    var r = '';
    r += cube() + ' \n';
    r += mul() + ' \n';
    alert(r);
  }

и посмотрите результат в профайлере Chrome:

mul: 106ms 
cube: 87ms

Как это возможно?

4b9b3361

Ответ 1

Ваше утверждение неверно. куб не быстрее, чем mul, и ваш пример этого не доказывает.

Фактически, происходит то, что внутренности выполнения Javascript занимают больше времени, чем фактическое умножение, что приводит к очень похожим временам для mul и cube. Я запустил две функции в цикле, просто чтобы увеличить разницу, а профайлер показывает 20219 против 20197, что является незначительным. И BTW, куб здесь "медленнее".

Кроме того, этот метод профилирования не работает, потому что и Chrome, и Firefox оптимизируют многое, прежде чем делать математику внутри циклов. То, что вы думаете, это цикл, может очень хорошо использовать кешированное значение или даже математическую функцию, которую знает оптимизация, возвращает тот же результат.

Вот код, который я использовал:

<script>
 var max = 0xffffff * 4;
  var step = 1 / max;
  function cube() {
    var result = 0.;
    for (var x = 0.; x < 1; x += step) {
      result += x * x * x;
    }
    return result;
  }
  function mul() {
    var result = 0.;
    for (var x = 0.; x < 1; x += step) {
      result += x * x;
    }
    return result;
  }
  function go() {
    var s='';
    for (var i=0; i<100; i++) {
        s+=cube();
        s+=mul();
    }
    console.log(s);
  }
  go();
</script>

Кроме того, в качестве справочного материала смотрите видео здесь: https://fosdem.org/2016/schedule/event/mozilla_benchmarking_javascript_tips/, где парень из Firefox объясняет, почему микрообнаружение на самом деле мало что значит.

Ответ 2

Это, вероятно, потому, что, поскольку все ваши номера ниже 1, функция куба добавляет меньшие числа, чем квадрат, и (я не уверен, действительно ли это на самом деле работает), поэтому занимает меньше времени. Это просто догадка. И поскольку числа настолько малы, что это также может быть связано с неадекватной точностью. Кроме того, я тестировал с цифрами более одного куба с ними медленнее.

Ответ 3

возможно, оптимизатор решает, что один из них может быть выполнен с векторными инструкциями, в то время как другой использует простой старый fmul. Я предполагаю, что "square" использует fmul и cube использует векторную инструкцию mulpd, которая может умножать до 4 удвоений в одной инструкции. Я добавил "квад", который сделал 4 умножения, и его время довольно близко к кубу. но когда я пошел на "пятерку", он замедлился медленнее, чем квадрат. Это косвенное свидетельство того, что векторные инструкции используются для куба и квадроцикла.

Было бы интересно увидеть результаты на процессоре Intel с процессором на планшете.

Ответ 4

В некоторых браузерах javascript запускается как интерпретируемый, тогда как JIT компилирует его в фоновом режиме. После компиляции javascript он начинает работать быстрее.