2015-01-05 3 views
4

Я сделал a jsPerf test, чтобы увидеть, были ли различия в производительности между аргументами или локальными переменными в функции в JavaScript.Chrome 39 JavaScript Performance Anomaly

В Firefox 34 практически не было различий. Однако в Chrome 39 компилятор, похоже, наносит большой вред. Посмотреть эти результаты:

Может кто-нибудь объяснить, почему это происходит?

+0

Просто для записи, равные результаты в IE 11. –

ответ

4

Прежде всего, для теста, который пытается измерить аргументы против поведения производительности локальных переменных, вы делаете слишком много в каждом случае - вы выделяете закрытие снова и снова, вы выделяете объект из литерала объекта, вы используете for-in. Все эти операции - это путь больше дороже, чем доступ к локальной переменной. Их затраты включают в себя и скрывают любой доступ к переменной стоимости.

Теперь аномалия, которую вы видите, связана с тем, что V8 не имеет быстрого пути для создания замыканий, содержащих литералы: есть FastNewClosureStub, но он используется только тогда, когда в закрытии нет литералов [1]. Это делает распределение закрытия более дорогостоящим в первом случае по сравнению со вторым - вы видите это отраженное в счете, поскольку распределение закрытия является довольно доминирующей частью вашего теста (он выделяет одно замыкание на op).

Если вы «спрятали» литеральное создание [2] в отдельную функцию, вы увидите аномалию. Примечание: такое скрытие не делает референтный тест более актуальным: все равно не измерение того, что вы хотите измерить.

В целом попытка захвата характеристик производительности переменного доступа в эталоне очень сложна, поскольку они обычно относятся к самым быстрым и наименьшим операциям даже в коде, создаваемом не оптимизирующим (базовым) компилятором. В наиболее распространенном случае, когда никакие переменные не захватываются, а область не содержит with, eval или arguments объект - между аргументами и доступом к локальной переменной не будет различий, скомпилированных в одну загрузку памяти.

[1] https://github.com/v8/v8-git-mirror/blob/9def087efcd844342c35f42628bac4ead49cac81/src/ia32/full-codegen-ia32.cc#L1213-L1218

[2] http://jsperf.com/variable-vs-variable-passed-as-an-argument-to-a-self-in/3

+0

Это было очень полезно. Спасибо за понимание! –