Разработчик V8 здесь. Короткий ответ: «это зависит от обстоятельств, не беспокойтесь об этом».
В общем, V8 (и другие движки, насколько мне известно) оптимизируются для каждой функции. Итак, в вашем примере, если и когда foo
оптимизирован, он не знает, будет ли его возвращаемое значение использоваться или игнорироваться, поэтому он не может оптимизировать его.
Исключением является встраивание: оптимизирующий компилятор имеет возможность встроить вызываемые функции, когда вызывающая функция оптимизирована, например, в этом примере:
function foo() {
// Do some FOO work...
return {};
}
function bar() {
foo();
// Do some BAR work...
}
Когда foo
оптимизирован, он будет (продолжать) возвращать только что выделенный пустой объект, независимо от того, откуда он вызван. Когда bar
оптимизирован, компилятор может решить встроить foo
, и после этого шага он увидит (собственное внутреннее представление гипотетической функции, например):
function bar() {
// Do some FOO work...
{};
// Do some BAR work...
}
И затем он может легко сбросить выделение неиспользуемых объектов там.
Тем не менее, как указывалось в комментариях к вопросу, это не то, о чем вам нужно беспокоиться. (Если только вы случайно не потратите огромное количество времени на построение дорогостоящих, но неиспользуемых возвращаемых значений - но это кажется маловероятным, потому что это довольно очевидная неэффективность, так что скорее всего, вы вообще не стали бы писать такой код.)
В частности, возврат некоторого значения, которое вы все равно вычислили, имеет ноль стоимость по сравнению с возвратом ничего, потому что каждая функция всегда что-то возвращает - если у нее нет оператора return
, тогда двигатель незаметно вставит return undefined;
за вас. Это означает, что function f1() {}
и function f2() { return undefined; }
будут компилироваться в один и тот же код. И если вы решили написать что-то вроде:
function overly_clever(need_result) {
let result = do_some_work();
if (result < 0) handle_error();
if (need_result) {
return result;
} else {
// Return nothing.
}
}
, тогда эта функция будет немного (неизмеримо) медленнее , чем если бы вы заменили все после пустой строки простым return result
, потому что «пустая» ветвь else
(с автоматически вставляемой return undefined;
) не быстрее, чем return result
, поэтому оценка условия need_result
- пустая трата времени.
Итак , короче: не беспокойтесь об этом. Напишите разумный код, позвольте движку позаботиться о его оптимизации.
(Для полноты: если вы действительно чувствуете необходимость выполнить ручную оптимизацию, позвольте ему руководствоваться измерением: профилируйте ваше приложение, чтобы увидеть, где большую часть времени тратится на измерение эффекта любых попыток изменения, чтобы убедиться, что они эффективны. Не используйте микробенчмарки, потому что они, как правило, вводят в заблуждение.)