Оптимизируют ли самые современные компиляторы JavaScript/ECMAScripte ненужное присвоение переменных при возврате значения из вызова функции?

Скажем, мы внутри объекта, который реализует обработку файлов. Я хочу написать код для удобства чтения.

Пример кода, в котором может быть сложно определить тип возвращаемого значения, особенно при наличии нескольких вызовов вложенных функций:

function create() {
    return doCreateAction();
}

Этот пример более читабелен, если ввести уточняющую переменную:

function create() {
    var fileHandle = doCreateAction();
    return fileHandle;
}

Теоретически, вторая версия может работать идентично, потому что компилятор должен в любом случае временно сохранять результат из doCreateAction() (возможно, внутри некоторой скрытой, анонимной, кратковременной временной переменной). Этот код медленнее при назначении именованной переменной?

1 ответ

Я бы сказал, что либо они оптимизируют переменную, либо это не стоит беспокоить; и что в любом случае вам нужно жарить больше рыбы.:-) Но здесь есть интересный аспект, связанный с хвостовыми вызовами.

Но сначала, с точки зрения простой производительности: эмпирически, этот упрощенный синтетический тест предполагает, что производительность функции не меняется в зависимости от того, существует ли переменная. Также обратите внимание, что минификатор, скорее всего, удалит эту переменную до того, как движок JavaScript заглянет, если вы используете приличный минификатор.

Переход к хвостовым вызовам: Как вы, возможно, знаете, начиная с ES2015 в строгом режиме спецификация требует оптимизации хвостового вызова, что означает, что когда функция A возвращает результат вызова функции B, а не B возвращает свой результат A, который затем возвращает его вызывающей стороне, A передает управление непосредственно B, который затем возвращает результат вызывающей стороне. Это более эффективно несколькими способами (избегает создания другого кадра в стеке, избегает прыжка).

Движки JavaScript все еще работают над реализацией TCO. (Следите за прогрессом V8 здесь, например.) Но если я правильно прочитал спецификацию (не значит, подвиг), ваш первый пример имеет doCreateAction в хвостовой позиции и т. д. можно оптимизировать с помощью TCO, но ваша вторая - нет. И TCO в настоящее время в V8 в узле 8.2.1 (v5.8.283.41) действительно оптимизирует первое, но не второе.

Таким образом, в этом отношении могут возникнуть последствия, в зависимости от того, достигли ли двигатели точки внедрения TCO, как указано, они выходят за рамки спецификации для таких случаев, когда это, по сути, является хвостовым вызовом.


Раньше я был довольно строг в отношении использования переменной в этой ситуации для целей отладки; Однако умеренно последние версии devtools в Chrome делают его ненужным для этой цели (и, конечно, минификатор удалит его в любом случае): если вы вступите в returnвы видите возвращаемое значение в локальном списке переменных. Конечно, это полезно, только если вы используете devtools в Chrome (например, Firefox этого не делает [пока?]).

Другие вопросы по тегам