Javascript Двигатели Преимущества - PullRequest
54 голосов
/ 26 января 2010

Я запутался в механизмах JavaScript прямо сейчас. Я знаю, что V8 был большой проблемой, потому что он компилировал JavaScript в нативный код.

Затем я начал читать о Mozilla SpiderMonkey , который, насколько я понимаю, написан на C и может компилировать JavaScript. Так чем же это отличается от V8 и если это правда, почему Firefox этого не делает?

Наконец, Rhino буквально компилирует байтовый код JavaScript в Java, чтобы вы могли получить все преимущества скорости Java? Если нет, то почему люди не запускают V8 при написании сценариев на своих рабочих столах?

Ответы [ 4 ]

78 голосов
/ 27 января 2010

Существуют различные подходы к выполнению JavaScript, даже при выполнении JIT. V8 и Nitro (ранее известный как SquirrelFish Extreme) предпочитают делать JIT с целым методом, то есть, когда они сталкиваются со скриптом, они компилируют весь код JavaScript до нативных инструкций, а затем просто выполняют это, как если бы это был скомпилированный код C. Вместо этого SpiderMonkey использует «отслеживающий» JIT, который сначала компилирует скрипт для байт-кода и интерпретирует его, но контролирует выполнение, ища «горячие точки», такие как циклы. Когда он его обнаруживает, он затем компилирует только этот горячий путь к машинному коду и выполняет его в будущем.

Оба подхода имеют свои плюсы и минусы. Целостный метод JIT гарантирует, что весь исполняемый JavaScript будет компилироваться и выполняться как машинный код, а не интерпретироваться, что в целом должно быть быстрее. Однако в зависимости от реализации это может означать, что механизм тратит время на компиляцию кода, который никогда не будет выполнен или может быть выполнен только один раз и не является критичным для производительности. Кроме того, этот скомпилированный код должен храниться в памяти, что может привести к увеличению использования памяти.

Трассирующий JIT, реализованный в SpiderMonkey, может генерировать чрезвычайно специализированный код по сравнению с JIT с целым методом, поскольку он уже выполнил код и может рассуждать о типах переменных (таких как обработка индексной переменной в цикле for как нативное целое число), где JIT целого метода должен был бы обрабатывать переменную как объект, потому что JavaScript не типизирован, и тип мог измениться (SpiderMonkey просто «обвалит» трассировку в случае сбоя предположения и вернется к интерпретации байт-кода). Однако отслеживание JIT SpiderMonkey в настоящее время не работает эффективно в коде со многими ветвями, так как трассировки оптимизированы для отдельных путей выполнения. Кроме того, есть некоторые накладные расходы, связанные с мониторингом выполнения, прежде чем принять решение о компиляции трассы, а затем переключить выполнение на эту трассировку. Кроме того, если трассировщик делает предположение, которое впоследствии нарушается (например, изменяющий тип переменной), стоимость отклонения трассировки и возврата к интерпретации, вероятно, будет выше, чем при использовании JIT для всего метода.

11 голосов
/ 26 января 2010

V8 - самый быстрый, потому что он компилирует весь JS в машинный код.

SpiderMonkey (что использует FF) тоже быстрый, но компилируется в промежуточный байт-код, а не в машинный код. Это главное отличие V8. РЕДАКТИРОВАТЬ - Новые версии Firefox поставляются с более новой версией SpideMonkey; TraceMonkey. TraceMonkey выполняет JIT-компиляцию критических частей и, возможно, другие интеллектуальные оптимизации.

Rhino компилирует Javascript в классы Java, что позволяет вам в основном писать "Java" -приложения в Javascript. Rhino также используется как способ интерпретации JS в бэкэнде и манипулирования им, а также для полного понимания кода, такого как рефлексия. Это используется, например, Компрессором YUI.

Причина, по которой Rhino используется вместо V8 повсеместно, вероятно, в том, что V8 является относительно новым, поэтому многие проекты уже используют Rhino / Spidermonkey в качестве своего движка JS, например виджеты Yahoo. (Я предполагаю, что вы имеете в виду «скрипты на своих рабочих столах»)

Edit- Эта ссылка также может дать некоторое представление о том, почему SpiderMonkey так широко используется. Какой движок Javascript вы бы встроили в свое приложение?

6 голосов
/ 26 января 2010

Если вы хотите увидеть, как складываются различные механизмы JavaScript в браузере, установите Safari 4 (да, он теперь работает и в Windows!), Chrome V8, Firefox 3.5 и IE 8 (если вы используете Windows) и запустить тест:

http://www2.webkit.org/perf/sunspider-0.9/sunspider.html

Я полагаю, что, как сказал Пойнти выше, новый Firefox 3.5 использует TraceMonkey, который также компилирует код для оперативного вмешательства на лету, используя некоторую форму JIT. Так что стоит сравнивать с V8 несколько выгодно. По крайней мере, он не будет в 10 раз медленнее, чем V8, как Firefox 3 SpiderMonkey (без JIT).

Для меня ... Safari 4.0.3 был в 2,5 раза быстрее, чем Tracemonky в Firefox 3.5.3 на Win XP. IE8 был намного медленнее. В данный момент у меня не установлен Chrome.

Не знаю, как Rhino компилируется в байт-код Java. Если он по-прежнему интерпретирует динамические функции Javascript, такие как возможность добавлять атрибуты к экземплярам объектов во время выполнения (пример obj.someNewAttribute = "someValue", что разрешено в Javascript) ... Я не уверен, что он полностью "скомпилирован" "байт-код, и вы можете не получить более высокую производительность, кроме как вам не нужно компилировать из текста исходного кода Javascript при каждом запуске Javascript. Помните, что Javascript допускает очень динамический синтаксис, такой как eval («x = 10; y = 20; z = x * y»); Это означает, что вы можете создавать строки кода, которые компилируются во время выполнения. Вот почему я думаю, что Rhino будет интерпретирован / скомпилирован в смешанном режиме, даже если вы скомпилировали байт-код JVM.

JVM все еще является переводчиком, хотя и очень хорошим с поддержкой JIT. Поэтому мне нравится думать о Rhino-on-JVM как о двух уровнях интерпретатора (интерпретатор-интерпретатор) или интерпретатора ^ 2. Принимая во внимание, что большинство других ваших движков Javascript написаны на C, и поэтому они должны работать как интерпретатор ^ 1. Каждый уровень интерпретатора может добавить 5-10-кратное снижение производительности по сравнению с C или C ++ (например, Perl или Python или Ruby), но с JIT снижение производительности может быть намного ниже, порядка 2-4x. И у JVM есть один из самых надежных и зрелых двигателей JIT.

Таким образом, ваш пробег определенно будет отличаться, и вы, вероятно, выиграете от некоторых серьезных тестов, если вы хотите получить реальный ответ для предполагаемого приложения на собственном оборудовании и ОС.

Носорог не может быть слишком медленным, поскольку я знаю, что многие люди используют его. Я думаю, что его главная привлекательность заключается не в его скорости, а в том, что он прост в написании / легком весе / встраиваемом / интерпретаторе, который связан с библиотеками Java, что делает его идеальным для создания сценариев / настройки / расширения вашего программного проекта. Некоторые текстовые редакторы, такие как UltraEdit, даже встраивают Javascript в качестве альтернативного механизма макросов. Кажется, что каждый программист может довольно легко наткнуться на javascript, так что его легко понять.

Одним из преимуществ Rhino является то, что он работает практически везде, где работает JVM. По моему опыту, попытка получить автономную версию TraceMonkey или SpiderMonkey для сборки и запуска из командной строки может быть немного болезненной в таких системах, как Windows. А встраивание в собственное приложение может занять еще больше времени. Но окупаемость наличия встраиваемого языка стоила бы его для большого проекта по сравнению с необходимостью «свернуть свое» решение мини-сценариев, если вы этого хотите.

Сценарии с Rhino действительно просты, если у вас есть Java и jar rhino, вы просто пишете свой javascript и запускаете его из командной строки. Я все время использую его для простых задач.

3 голосов
/ 26 января 2010

Чтобы ответить на вопрос, почему нативный код против байт-кода ...

Собственный код работает быстрее и для Google является стратегическим выбором, поскольку они планируют использовать JS, по крайней мере один из них - ChromeOS.

Хорошее видео по этому вопросу выложено на 9 канале с интервью с Ларсом Баком, который стоит за V8 здесь

...