В Node.js вроде есть какие-то пулы потоков, так что оно что-то все-таки умеет сейчас делать параллельно и сумеет наверное больше чем одно ядро загрузить.
Вообще несколько node.js может оказаться удобнее чем одна node.js с несколькими инстансами v8 внутри. Процессы ведь полностью изолированы друг от друга. Один может упасть, а остальные продолжат работу.
Эрлангеры (эрлангисты?), иногда аналогичные идеи высказывают — если случился форсмажор удобнее просто сервер уронить и переподнять, чем пытаться исправить его последствия.
несколько инстансов на один процесс — пожалуйста, с изолятами (отдельная экспериментальная ветка v8 в официальном репозитории).
не крашится по OOM? это в некотором роде философия обработки ошибок… ООМ это критическая ситуация, которая не должна случаться во время работы приложения. Много ли их способно грамотно продолжить работу, если где-то глубоко по стэку отказали в выделении памяти? сомневаюсь.
Лично я отношусь к node.js положительно: пользовательская база от этого расширяется.
Оценить пригодность V8 в целом для написания произвольного серверного приложения я не могу, приложения то бывают разные. Страничка на PHP тоже в каком-то смысле серверное приложение.
Из подводных камней могу упомянуть проблемы со сборкой мусора на боооольших кучах и общий лимит кучи 1.9gb.
наивный такой пример (не соответствует полностью действительности, но суть передает):
в оптимизированном коде загрузка поля будет выглядить примерно так:
if not (object obj has field x by offs y) then deoptimize;
v = *(addressof(obj) + y)
в не оптимизированном:
if (object obj has field x by offs y) then
v = *(addressof(obj) + y) ; inlined cache for common case
else
GenericLoadProperty(obj, 'x') ; call runtime function
end
вот этот код v = *(addressof(obj) + y) верен только в предположениях относительно «типа» obj. проверка if not (object obj has field x by offs y) then deoptimize; называется guard'ом, она проверяет корректность предположений.
Может возникнуть вопрос: проверка же вроде и там и там есть, в чем же цимес?
Существенное отличие тут в том, что в оптимизированный код перестает выполняться когда уловие нарушается: получается, что если проверка прошла, то предположение верно на оставшемся куске оптимизированного кода (либо на «оставшемся» куске кода без побочных эффектов, зависит от свойства которое проверяется). Это открывает множество возможностей для оптимизации, которые до этого были закрыты постоянными if then else end в коде. Ведь после end нельзя было сказать, какая ветвь исполнилась.
для таких оптимизаций, как вычисление инвариантов циклов, вынесение общих подвыражений и кода в ветвлениях, последовательное распределение регистров и встраивание.
«linear scan» это название семейства алгоритмов распределения регистров, которые оперируют на линеаризованном представлении графа потока управления, дословно не переводится.
«вычисление инвариантов циклов» => перемещение или вынос инвариантов цикла.
В случае, если результирующий код не будет быстрее, есть возможность вернуться к выполнению кода, полученного базовым компилятором.
Дело не в том будет ли результирующий код быстрее, а в том выполняются ли предположения, при которых он был скомпилирован (предположения могут касаться, например, типов значений, которые могут оказаться в определенной переменной, или структуры цепочки прототипов некоторого объекта). Если оптимизированный код обнаруживает, что предположения, от которых зависит его корректная работа, нарушаются, то происходит возврат к неоптимизированному коду, который всегда корректен.
во многих функциональных языках есть такие штуки как «каррирование» (currying) и «частичное применение» (partial application). Function.bind — это фактически удобный способ делать частичное применение в Javascript.
. В случае с bind создается обертка для функции, то есть это отдельная специальная структура, которая содержит ссылку на функцию, контекст и список значений для статичных параметров (если такие есть).
Поддерживать таким образом bind мало удовольствия — получается во всей среде исполнения надо быть очень аккуратным, потому что есть полноценные функции, а есть какие-то куцые обертки, которые с одной стороны требуют особых преплясываний при вызове, а с точки зрения языка вроде бы являются «полноценными функциями». Если вы посмотрите, например, в файлик v8natives.js, то обнаружите, что реализация bind в V8 создаёт обычную функцию.
при использовании bind, хранится ссылка на вызываемую функцию, при использовании var self = this; — ссылка на сам объект, контекст для которого нам нужен.
вы хотите сказать, что если вы сделаете func.bind(this) то вам не придется хранить ссылку на this? =)
нода же запускается как
./node app.js
, а не как./shell node.js app.js
.Вообще несколько node.js может оказаться удобнее чем одна node.js с несколькими инстансами v8 внутри. Процессы ведь полностью изолированы друг от друга. Один может упасть, а остальные продолжат работу.
соответственно как напишите их использование, так все и загрузится.
не крашится по OOM? это в некотором роде философия обработки ошибок… ООМ это критическая ситуация, которая не должна случаться во время работы приложения. Много ли их способно грамотно продолжить работу, если где-то глубоко по стэку отказали в выделении памяти? сомневаюсь.
Оценить пригодность V8 в целом для написания произвольного серверного приложения я не могу, приложения то бывают разные. Страничка на PHP тоже в каком-то смысле серверное приложение.
Из подводных камней могу упомянуть проблемы со сборкой мусора на боооольших кучах и общий лимит кучи 1.9gb.
Недавно поправили парсер регулярных выражений, чтобы выбрасывал на нем исключение.
Рекомендую репортовать баг ExtJSовцам.
наивный такой пример (не соответствует полностью действительности, но суть передает):
в оптимизированном коде загрузка поля будет выглядить примерно так:
в не оптимизированном:
вот этот код
v = *(addressof(obj) + y)
верен только в предположениях относительно «типа» obj. проверкаif not (object obj has field x by offs y) then deoptimize;
называется guard'ом, она проверяет корректность предположений.Может возникнуть вопрос: проверка же вроде и там и там есть, в чем же цимес?
Существенное отличие тут в том, что в оптимизированный код перестает выполняться когда уловие нарушается: получается, что если проверка прошла, то предположение верно на оставшемся куске оптимизированного кода (либо на «оставшемся» куске кода без побочных эффектов, зависит от свойства которое проверяется). Это открывает множество возможностей для оптимизации, которые до этого были закрыты постоянными
if then else end
в коде. Ведь после end нельзя было сказать, какая ветвь исполнилась.«linear scan» это название семейства алгоритмов распределения регистров, которые оперируют на линеаризованном представлении графа потока управления, дословно не переводится.
«вычисление инвариантов циклов» => перемещение или вынос инвариантов цикла.
Дело не в том будет ли результирующий код быстрее, а в том выполняются ли предположения, при которых он был скомпилирован (предположения могут касаться, например, типов значений, которые могут оказаться в определенной переменной, или структуры цепочки прототипов некоторого объекта). Если оптимизированный код обнаруживает, что предположения, от которых зависит его корректная работа, нарушаются, то происходит возврат к неоптимизированному коду, который всегда корректен.
enclosure => Closure Compiler [ code.google.com/closure/compiler/ ]
GIT => GWT [ code.google.com/webtoolkit/ ]
но да ему сам бог велит — семантика у lua простая и изящная, компилировать и оптимизировать одно удовольствие.
Все уже починили :-)
Total tests: 27 Passed: 27 Failed: 0 Could not load: 0
p.s. «карри» — это вообще приправа на основе куркумы =)
во многих функциональных языках есть такие штуки как «каррирование» (currying) и «частичное применение» (partial application).
Function.bind
— это фактически удобный способ делать частичное применение в Javascript.Поддерживать таким образом bind мало удовольствия — получается во всей среде исполнения надо быть очень аккуратным, потому что есть полноценные функции, а есть какие-то куцые обертки, которые с одной стороны требуют особых преплясываний при вызове, а с точки зрения языка вроде бы являются «полноценными функциями». Если вы посмотрите, например, в файлик v8natives.js, то обнаружите, что реализация bind в V8 создаёт обычную функцию.
вы хотите сказать, что если вы сделаете func.bind(this) то вам не придется хранить ссылку на this? =)