Преимущества Javascript Engines
Я запутался в JavaScript-движках прямо сейчас. Я знаю, что V8 был большой проблемой, потому что он скомпилировал JavaScript для собственного кода.
Затем я начал читать о Mozilla SpiderMonkey, который из того, что я понимаю, написан на C и может скомпилировать JavaScript. Итак, как это отличается от V8, и если это так, почему Firefox не делает этого?
Наконец, Rhino буквально компилирует байтовый код JavaScript в Java, чтобы получить все преимущества Java на скорости. Если нет, почему люди не запускают V8 при написании сценариев на своих рабочих столах?
Ответы
Ответ 1
Существуют различные подходы к выполнению JavaScript, даже при выполнении JIT. V8 и Nitro (ранее известный как SquirrelFish Extreme) решили сделать целый метод JIT, что означает, что они компилируют весь код JavaScript до встроенных инструкций, когда они сталкиваются с script, а затем просто выполняют это, как если бы он был скомпилирован C-кодом. SpiderMonkey использует вместо этого "трассировку" JIT, которая сначала компилирует script в байт-код и интерпретирует его, но контролирует выполнение, ища "горячие точки", такие как циклы. Когда он обнаруживает один, он затем компилирует только этот горячий путь к машинным кодам и выполняет это в будущем.
Оба подхода имеют недостатки и недостатки. Whole-method JIT гарантирует, что весь выполняемый JavaScript будет скомпилирован и запущен как машинный код, а не интерпретирован, что в целом должно быть быстрее. Однако в зависимости от реализации это может означать, что двигатель проводит компиляцию кода времени, который никогда не будет выполняться или может выполняться только один раз и не критичен по производительности. Кроме того, этот скомпилированный код должен храниться в памяти, поэтому это может привести к увеличению использования памяти.
Трассировка JIT, реализованная в SpiderMonkey, может создавать чрезвычайно специализированный код по сравнению с JIT целого метода, поскольку он уже выполнил код и может спекулировать на типах переменных (например, обрабатывать индексную переменную в цикле for как нативное целое), где JIT целого метода должен обрабатывать переменную как объект, потому что JavaScript является нетипизированным, и тип может измениться (SpiderMonkey будет просто "отпадать" от трассировки, если это предположение не удастся, и вернуться к интерпретации байт-кода). Тем не менее, трассировка SpiderMonkey JIT в настоящее время не работает эффективно с кодом со многими ветвями, поскольку трассы оптимизированы для одиночных путей выполнения. Кроме того, некоторые надбавки участвуют в мониторинге, прежде чем принимать решение о компиляции трассировки, а затем переключать выполнение на эту трассировку. Кроме того, если трассировщик делает допущение, которое позже нарушается (например, тип изменения переменной), стоимость падения следа и возврата к интерпретации, вероятно, будет выше, чем при использовании JIT целого метода.
Ответ 2
V8 является самым быстрым, поскольку он компилирует все JS для машинного кода.
SpiderMonkey (то, что использует FF) также очень быстрый, но компилируется в промежуточный байт-код, а не в машинный код. Это большая разница с V8. EDIT. Новые версии Firefox поставляются с более новым вариантом SpideMonkey; TraceMonkey. TraceMonkey делает JIT компиляцию критических частей и, возможно, другую интеллектуальную оптимизацию.
Rhino компилирует Javascript в классы Java, что позволяет вам в основном писать приложения Java в Javascript. Rhino также используется как способ интерпретировать JS в бэкэнд и манипулировать им и иметь полное понимание кода, например, отражение. Это используется, например, компрессором YUI.
Причина, по которой Rhino используется вместо V8 повсюду, вероятно, потому, что V8 является относительно новым, поэтому многие проекты уже используют Rhino/Spidermonkey в качестве своего JS-движка, например, виджеты Yahoo. (Я предполагаю, что вы имеете в виду "скрипты на своих рабочих столах" )
Edit-
Эта ссылка может также дать некоторое представление о том, почему SpiderMonkey так широко принят.
Какой механизм Javascript вы встраиваете в свое приложение?
Ответ 3
Если вы хотите увидеть, как складываются различные браузерные Javascript-механизмы, установите Safari 4 (да, теперь он работает и в Windows!), Chrome V8, Firefox 3.5 и IE 8 (если вы на окнах) и запустите тест:
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.5x быстрее, чем 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 или С++ (например, Perl или Python или Ruby), но с JIT поражение производительности может быть значительно ниже порядка 2-4x. И JVM имеет один из самых надежных и зрелых двигателей JIT.
Таким образом, ваш пробег определенно изменится, и вы, вероятно, выиграете от выполнения некоторых серьезных тестов, если вы хотите получить реальный ответ для своего предполагаемого приложения на своем собственном оборудовании и ОС.
Rhino не может быть слишком ужасно медленным, так как я знаю, что многие используют его. Я думаю, что главная привлекательность - это не его скорость, а тот факт, что это простой в использовании код/легкий/встраиваемый/интерпретатор, который имеет крючки в Java-библиотеках, что делает его идеальным для сценариев/конфигурации/расширяемости вашего программного проекта. Некоторые текстовые редакторы, такие как UltraEdit, даже встраивают Javascript в качестве альтернативного механизма сценариев макросов. Кажется, что каждый программист способен легко споткнуться через javascript, поэтому его легко поднять.
Одним из преимуществ Rhino является то, что он работает практически везде, где работает JVM. По моему опыту, попытка создать автономный TraceMonkey или SpiderMonkey для создания и запуска из командной строки может быть немного болезненной в таких системах, как Windows. И внедрение в ваше приложение может быть еще более трудоемким. Но окупаемость наличия вложенного языка будет стоить этого для большого проекта, по сравнению с необходимостью "сворачивать свое" мини-скриптовое решение, если это то, что вы хотите сделать.
Сценарии с Rhino очень легки, если у вас есть Java и рин-ривер, вы просто пишете свой javascript и запустите его из командной строки. Я использую его все время для простых задач.
Ответ 4
Чтобы ответить на вопрос, почему собственный код Vs Байт-код...
Нативный код быстрее и для Google - стратегический выбор, потому что у них есть план JS, один из которых, по крайней мере, является ChromeOS.
Хорошее видео об этом вопросе опубликовано на Channel9 с интервью с Ларсом Баком, человек, стоящий за V8, можно найти здесь