Как различные проекты оптимизации Javascript влияют на производительность DOM? - PullRequest
5 голосов
/ 02 января 2009

В Javascript через проекты Tracemonkey, Squirrelfish и V8 идет много капиталовложений в компьютерную науку. Рассматривает ли какой-либо из этих проектов (или другие) производительность операций DOM или они связаны исключительно с вычислениями Javascript?

Ответы [ 2 ]

13 голосов
/ 02 января 2009

На производительность чистых операций DOM (getElementById / Tagname / Selector, nextChild и т. Д.) Это не влияет, так как они уже в чистом C ++.

То, как усовершенствования механизма JS будут влиять на производительность, зависит в определенной степени от конкретных методов, используемых для повышения производительности, а также от производительности моста DOM-> JS.

Примером первой является зависимость TraceMonkey от всех вызовов функций JS. Поскольку трассировка эффективно указывает путь выполнения в любой точке, где JS выполняет поиск кода, который не может быть встроен (собственный код, истинная полиморфная рекурсия, обработчики исключений), трассировка прерывается и выполнение возвращается к интерпретатору. Разработчики TM проделывают довольно большую работу, чтобы улучшить объем кода, который можно отследить (включая обработку полиморфной рекурсии), однако реально отследить вызовы произвольных собственных функций (например, DOM) невозможно. По этой причине я считаю, что они смотрят на реализацию большего количества DOM в JS (или, по крайней мере, в дружественной для JS манере). Тем не менее, когда код прослеживается, TM может выполнять исключительно хорошую работу, поскольку она может понизить большинство «объектов» до более эффективных и / или собственных эквивалентов (например, использовать машинные целые числа вместо реализации JS Number).

JavaScriptCore (именно там живет SquirrelFish Extreme) и V8 имеют более схожий подход в том, что оба они JIT-код всего JS немедленно и генерируют код, который является более умозрительным (например, если вы делаете a*b, они генерируют код, который предполагает a и b являются числами и возвращаются к чрезвычайно медленному коду, если это не так). Это имеет ряд преимуществ по сравнению с трассировкой, а именно то, что вы можете выполнять джит весь код независимо от того, вызывает ли он собственный код или генерирует исключения, и т. Д., Что означает, что один вызов DOM не снизит производительность. Недостатком является то, что весь код является спекулятивным - TM будет выполнять внутренние вызовы Math.floor и т. Д., Но лучшее, что может сделать JSC / V8, будет эквивалентно a=Math.floor(0.5) -> a=(Math.floor == realFloor) ? inline : Math.floor(0.5), что требует затрат как по производительности, так и по использованию памяти, это также не особенно осуществимо. Причиной этого является предварительная компиляция, в то время как TM только код JIT после ее запуска (и поэтому точно знает, какая функция была вызвана), JSC и V8 не имеют реальной основы для такого предположения и в основном должны догадываться (и в настоящее время ни одна из них не пытается) этот). Единственное, что V8 и JSC делают, чтобы попытаться компенсировать эту проблему, это отследить то, что они видели в прошлом, и включить это в путь исполнения, оба используют комбинацию методов для этого кеширования, особенно в горячих случаях. они перезаписывают небольшие части потока инструкций, а в других случаях они хранятся вне кэша каналов. В общем, если у вас есть код, который идет

a.x * a.y

V8 и JSC будут проверять «неявный тип» / «Структура» дважды - один раз для каждого доступа, а затем проверять, что a.x и a.y оба числа, тогда как TM сгенерирует код, который проверяет тип a только один раз и может (при прочих равных условиях) просто умножить a.x и a.y, не проверяя, являются ли они числами.

Если вы смотрите на чистую скорость выполнения, в настоящее время есть что-то смешанное, так как каждый движок, кажется, лучше выполняет определенные задачи, чем другие - TraceMonkey выигрывает во многих тестах по чистой математике, V8 выигрывает в сильно динамичных случаях, JSC выигрывает, если есть смесь. Конечно, хотя сегодня это действительно так, завтра может и не быть, поскольку мы все усердно работаем над повышением производительности.

Другая проблема, о которой я упомянул, была стоимость привязки DOM <-> JS - это может сыграть очень важную роль в производительности сети, лучшим примером этого является Safari 3.1 / 2 против Chrome в тесте Dromaeo. Chrome основан на ветке Safari 3.1 / 2 WebKit, поэтому можно с уверенностью предположить, что производительность DOM одинакова (разница в компиляторе может вызвать некоторую разницу). В этом тесте Safari 3.1 / 2 на самом деле превосходит Chrome, несмотря на то, что JS-движок работает значительно медленнее, в основном это связано с более эффективными связями между JSC / WebCore (dom / render / etc из WebKit) и V8 / WebCore

В настоящее время просмотр привязок DOM TM кажется несправедливым, поскольку они не выполнили всю работу, которую хотят (увы), поэтому просто прибегают к интерпретатору: - (

..

Errmmm, это продолжалось несколько дольше, чем предполагалось, поэтому краткий ответ на оригинальный вопрос "это зависит": D

4 голосов
/ 02 января 2009

Это чистый JavaScript. Если конкретный вызов метода DOM не реализован в JS, они будут иметь незначительный эффект (не говоря уже о том, что не было сделано работы по сокращению накладных расходов таких вызовов).

Оптимизация DOM - это целый 'простой чайник из белок обезьян пауков рыба ... В игру вступают в игру механизмы верстки и даже рендеринга, и каждый браузер имеет собственную стратегию внедрения и оптимизации.

...