Как сделать microbenchmark с console.time, чтобы измерить небольшие различия в оптимизации компилятора? - PullRequest
2 голосов
/ 30 марта 2019

Этот код является адаптацией этого другого ... Это некрасивый код, но вопрос заключается в том, «как сделать тест».

  1. Новая функция console.time измеряет «реальное время выполнения» или это не так надежно?Это действительно надежно для всех браузеров или может немного измениться?PS: лучше использовать Date.now() (или что-то вроде Unix-терминала time), внешнюю временную привязку?

  2. Как проверить "оптимизацию компилятора" как игнорирование цикла, который ничего не делает?

Предполагается, что приведенный ниже эталон должен измерять стоимость операций == и ===, которые примерно одинаковы.Проблема в том, что каждый браузер (Firefox и Chorme) выдает различное среднее время ... Итак,

Имеет ли смысл использовать «среднее время для всех браузеров», когда оптимизации являются противоположными?Есть еще один способ оценить время выполнения?

Проверьте сами в разных браузерах или также с NodeJs ... И помните, что не обычная производительность(«Что быстрее?»), но мера реальности , способ проверить, что компиляторы делают (в среднем) для реализации предписаний ECMA 262.

var testString = "444442";
var testNumber = 444442;
var testString2 = "444443";
var testObject = {};
var testObject2 = {x:1};

const MAX = 1000000;
var name;
var result;

name='===';
result = 0;
console.time('Operation '+name);
for(var i = 0; i < MAX; i++){
    result += Number(
       (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
      )
      testNumber++
}
console.timeEnd('Operation '+name);

var result0 = result;

name='=='
result = 0;
console.time('Operation '+name);
var result = null;
for(var i = 0; i < MAX; i++){
  result += Number(
    (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
  )
}
console.timeEnd('Operation '+name);

if (result0 != result)
console.log("OOPS BUG, result0 differing result: ", result0, result)

name='NoOp'
result = 0;
console.time('Operation '+name);
for(var i = 0; i < MAX; i++){
    result =  true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true
}
console.timeEnd('Operation '+name);

Пример результатов (обнуление мс)

В Firefox:

Операция ===: 80 мс Операция ==: 200мс Операция NoOp: 8 мс

On Chrome:

Операция ===: 21 мс Операция ==: 27 мс Операция NoOp: 22 мс

В NodeJS:

Операция ===: 108 мс Операция ==: 152 мс Операция NoOp: 9 мс

Вывод: === немного быстрее во всех компиляторах.


Проблема : запуск другого процитированного кода, из этого ответа ("Тест Рика"),

В Firefox:

Операция ===: 1089 u Операция ==: 280 u Операция NoOp: 281 u

On Chrome:

Операция ===: 352 u Операция ==: 349 u Операция NoOp: 349 u

On NodeJS:

Операция ===: 201 u Операция ==: 387 u Операция NoOp: 195 u

Вывод: == (не ===) быстреев браузерах, но наоборот для Node.


Окончательные выводы: нет конвергенциирезультатов тестов, даже при использовании большего количества циклов и т. д. Похоже, что тест Рика подвергается оптимизации (которая изменяется по сравнению с компиляторами), а вышеизложенное здесь нет.

Окончательные выводы: сходимость результатов тестов отсутствует,даже при использовании большего количества циклов и т. д. Кажется, что тест Рика подвергается (зависит от компилятора) оптимизации, а вышеупомянутый тест (на этой странице) - нет.

PS: конечно, в идеале (по спецификации)операторы == и === имеют одинаковое время при сравнении одинаковых типов данных, поэтому трудно измерить разницу ... Но это вопрос, я хочу проверить эту небольшую разницу с console.time.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...