Вы должны пропустить. Для вашего конкретного случая:
db.person.find().snapshot().forEach(
function (elem) {
db.person.update(
{
_id: elem._id
},
{
$set: {
name: elem.firstname + ' ' + elem.lastname
}
}
);
}
);
Закорачивающие булевы выражения точно эквивалентны некоторому набору вложенной IFS, так так эффективны, как это было бы.
Если b не имеет побочных эффектов, он может все еще быть выполнен параллельно с (для любого значения "в параллели", включая конвейерную обработку).
Если b имеет побочные эффекты, которые не может отменить архитектура ЦП, когда предсказание ветвлений перестало работать затем да, это могло бы потребовать задержек, которые не были бы там, если бы обе стороны всегда оценивались. Таким образом, это - что-то для взгляда на то, если Вы действительно когда-либо находите, что закорачивающие операторы создают узкое место производительности в Вашем коде, но не стоящие волнения об иначе.
Но замыкание накоротко используется для потока управления так же как для сохранения ненужной работы. Это распространено среди языков, которые я использовал, например, идиома Perl:
open($filename) or die("couldn't open file");
идиома оболочки:
do_something || echo "that failed"
или идиома C/C ++/Java/etc:
if ((obj != 0) && (obj->ready)) { do_something; } // not -> in Java of course.
Во всех этих случаях Вам нужно замыкание накоротко, так, чтобы RHS был только оценен, если LHS диктует, что это должно быть. В таких случаях нет никакого смысла сравнивающего производительность с альтернативным кодом, это неправильно!
В зависимости от контекста это можно также назвать, "Охраняя".
И я видел его на примерно каждом языке, я работал в - который продвигает близко к дюжине.
Единственный поток последователен поэтому, если у Вас будет две IFS, то первое будет, конечно, оценено перед вторым, таким образом, я не вижу различия на этом. Я использую УСЛОВНУЮ ОПЕРАЦИЮ И (который является тем, какой && называют afaik), намного больше, чем вложенная IFS. Если я хочу проверить что-то, что может требовать времени для оценки, я делаю более простой тест сначала затем более твердый после условного выражения и.
a = obj.somethingQuickToTest() && obj.somethingSlowToTest();
кажется, несколько не отличается, чем
a = false;
if(obj.somethingQuickToTest())
a = obj.somethingSlowToTest();
я только услышал о нем как короткое замыкание. в конвейере не делает следующего op, который входит, зависят от результата если оператор? если это так, это было бы более оптимизированный, таким образом, это не должно будет тестировать два значения каждый раз.
Я ничего не знаю о конвейерной обработке, но закорачиваю оценку, типичная функция многих языков (и это - также имя, я знаю это). В C && и другие операторы определяют точку последовательности точно так же, как; оператор делает, таким образом, я не вижу, как оценка короткого замыкания так менее эффективна, чем просто использование нескольких операторов.
Большинство языков действительно закорачивает оценку булевых выражений. Я всегда слышал его называемый оценкой короткого замыкания.
Примером в вопросе является довольно упрощенный пример, который действительно не обеспечивает большую часть выигрыша в производительности. Выигрыш в производительности прибывает, когда выражения сложны для оценки.
Как пример того, когда это было бы хорошо, воображают игровую программу, которая имеет что-то как:
if (someObject.isActive() && someOtherObject.isActive() && CollisionDetection.collides(someObject, someOtherObject) {
doSomething();
}
В этом случае обнаружение коллизий является намного более дорогим, чем активные проверки. Было бы значительное повышение производительности, если бы было много неактивных объектов в системе.
Относительно того, эффективно ли замыкание накоротко, конвейерная обработка вряд ли окажет большую часть влияния на производительность. В ситуациях, где это могло оказать влияние, нет ничего, чтобы мешать компилятору тестировать несколько условий параллельно, пока эти тесты не имеют побочных эффектов. Плюс, современные центральные процессоры имеют несколько механизмов, полезных для того, чтобы улучшить конвейерную производительность разветвленного кода.
Вложенная IFS будет иметь тот же эффект как закорачивающий &&.
'Оценка короткого замыкания' является наиболее распространенным названием его, и Ваш друг неправ относительно этого являющийся редким; это очень распространено.
Короткое замыкание или минимальная оценка является просто синтаксическим сахаром для вложенной IFS. Для принятия это неэффективно, или вызывает остановы, случай преждевременной оптимизации. На данном этапе большинство компиляторов достаточно интеллектуально, чтобы правильно интерпретировать и оптимизировать эти операторы. Используя эти операторы может значительно уменьшить вложение и поэтому улучшить удобочитаемость кода, которая должна быть Вашей целью номер один.
Как может вложенный, если не останавливаются? На самом деле, если a и b являются оба переменными и не выражениями с побочными эффектами, они могут быть загружены параллельно хорошим компилятором. Нет никакого преимущества для использования большего количества IFS кроме увеличения Вашего количества строки. Действительно, это было бы худшим видом второго предположения компилятора.
Это назвало оценку короткого замыкания.
Во-первых, Ваш друг неправ. Оценка короткого замыкания (иначе минимальная оценка) доступна на большинстве языков и лучше, чем вложенная IFS для языков параллельного программирования (в этом случае первое из условий, которые возвраты заставят выполнение продолжать),
В любом случае даже на простом неязыке параллельного программирования я не вижу, как вложенная IFS была бы быстрее, поскольку выполнение заблокируется, пока первое условие не оценено.
VB.Net имеет другой синтаксис в зависимости от того, хотите ли Вы, чтобы он сорвал или нет. Из-за причин прежней версии поведение по умолчанию не состоит в том, чтобы сорвать. Синтаксис следующие
Не срывают
IF A And B THEN
...
END IF
Короткое замыкание
IF A AndAlso B THEN
...
END IF
Можно использовать Или / OrElse, если Вы хотите сорвать ИЛИ оператор. Который действительно хорош в ситуациях как следующее
If MyObj IsNot Nothing AndAlso MyObj.Value < SomeValue Then
....
End If
Лично, в то время как я понимаю, что срывание может ускорить вещи, это - определенно не что-то, что это очевидно из просто рассмотрения кода. Я видел, что неопытный разработчик запутался поведением. На что-то даже кажется, что это могло произойти или не в зависимости от флагов компилятора для уровня оптимизации. Мне нравится, как VB является подробным, о котором поведении Вы на самом деле хотите выполнить.
Я честно не волновался бы об этом. Тестирование булевской переменной действительно быстро. Замыкание накоротко только становится интересным / полезный, когда второе выражение имеет побочные эффекты:
if ( ConfirmAction() && DestroyAllData() )
Reboot();
... или зависит от первого теста:
if ( myDodgyVar != null && myDodgyVar.IsActive() )
DoSomethingWith(myDodgyVar);
Оценка короткого замыкания переводится в ответвления в ассемблере таким же образом, если операторы (ответвления являются в основном goto), что означает, что это не будет немного медленнее чем если бы операторы.
Ответвления обычно не останавливают конвейер, но процессор предположит, взято ли ответвление или нет, и если процессор является неправильным, что это должно будет сбросить все, что произошло, так как это высказало неправильное предположение от конвейера.
Оценка короткого замыкания является также наиболее распространенным названием его и найдена на большинстве языков в некоторой форме или другом.
Полезное короткое замыкание, которое я использую, является чем-то вроде этого:
if (a != null && a.equals(somevalue)) {
... do something.
}
Это, по-моему, очень читаемо, и функционирует вполне хорошо. Обычно я пробую, также избегают к большому вложению, потому что оно приводит к ужасному коду.
Все мое мнение все же.
Languages supporting short-circuiting:
Ada, Eiffel, ALGOL 68, C1, C++, C#, Java, R, Erlang, Standard ML, Javascript, MATLAB, Lisp, Lua, Scheme, OCaml, Haskell, Pascal,Perl, Ruby, PHP, Python, Smalltalk, Visual Basic .NET
Taken from Short-circuit evaluation