Кэширование переменных в JavaScript против других языков - PullRequest
1 голос
/ 28 февраля 2012

Кто-то недавно сказал мне, что это плохо:

var el = $("#myID");
$(el).addClass("a");
$(el).addClass("b");
$(el).addClass("c");

и что оно должно быть кэшировано так:

var $el = $("#myID");
$el.addClass("a");
$el.addClass("b");
$el.addClass("c");

Итак, мой вопрос, почему это не такоптимизироваться автоматически?В Java и других языках я думаю , что компилятор достаточно умен, чтобы выполнять кеширование самостоятельно.

то есть, это:

// myList is a List<String>
String str = myList.get(0);
String trimmed = str.trim();
String sub = str.substring(0, 5);
boolean abc = str.startsWith("abc");

не более эффективен, чем этот:

String trimmed = myList.get(0).trim();
String sub = myList.get(0).substring(0, 5);
boolean abc = myList.get(0).startsWith("abc");

Может ли кто-нибудь, кто знает больше о компиляторах, дать мне некоторое представление здесь?JavaScript просто такой тупой?Или это также верно для Java / других?

Ответы [ 2 ]

4 голосов
/ 28 февраля 2012

$(el) - это относительно дорогой вызов функции. Компилятор не может знать, что он всегда будет возвращать один и тот же (или, по крайней мере, эквивалентный) объект для каждого вызова, поэтому он не может выполнить предложенную вами оптимизацию.

Это не обязательно функция языка. Я уверен, что будут языки (возможно, где вы сможете объявить функцию как идемпотентную), в которой компилятор МОЖЕТ посчитать возвращаемое значение и выполнить эту оптимизацию.

Я почти уверен, что компилятор / оптимизатор Java может сделать это для относительно простых случаев.

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

1 голос
/ 28 февраля 2012

Вы думаете, что компилятор умнее, чем на самом деле!

Помните, что компилятор действительно знает только синтаксис и семантику языка, а не контракт API.Таким образом, даже если вы знаете, что $(el) всегда будет одним и тем же объектом, все, что знает компилятор, это «вызов функции $ с аргументом el», он не может предполагать, что функция возвратит тот же самыйзначение дано того же аргумента.(Например, подумайте о функции Math.random().) Аналогично, из вашего примера на Java мы можем знать, что myList.get(0) всегда будет одним и тем же объектом (обычно, если что-то не происходит, верно?), Но компилятор не может.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...