В этом коде:
if (value >= x && value <= y) {
когда value >= x
и value <= y
являются такими же правдоподобными, как false, без определенного шаблона, использование оператора &
выполняется быстрее, чем использование &&
?
В частности, я думаю о том, как &&
лениво оценивает правое выражение (т.е. только если LHS является истинным), что подразумевает условное, тогда как в Java &
в этом контексте гарантируется строгая оценка оба (булевых) подвыражения. Результат результата тот же самый.
Но пока оператор >=
или <=
будет использовать простую инструкцию сравнения, &&
должен включать ветвь, и эта ветвь восприимчива к ошибке предсказания ветвления - согласно этому очень известному вопросу: Почему быстрее обрабатывается отсортированный массив, чем несортированный массив?
Таким образом, принуждение выражения к отсутствию ленивых компонентов, несомненно, будет более детерминированным и не будет уязвимым для отказа прогнозирования. Правильно?
Примечания:
- Очевидно, что ответ на мой вопрос был бы "Нет", если бы код выглядел так:
if(value >= x && verySlowFunction())
. Я фокусируюсь на "достаточно простых" выражениях RHS. - там условная ветвь в любом случае (оператор
if
). Я не могу доказать себе, что это не имеет значения, и что альтернативные формулировки могут быть лучшими примерами, такими какboolean b = value >= x && value <= y;
- все это попадает в мир ужасающих микрооптимизаций. Да, я знаю:-)... интересно хотя?
Обновление Просто чтобы объяснить, почему мне интересно: я смотрел на системы, о которых писал Мартин Томпсон на своем блоке "Механическая симпатия" , после того, как он пришел, и сделал беседу об Aeron. Одним из ключевых сообщений является то, что у нашего оборудования есть все это волшебное вещество в нем, и мы, разработчики программного обеспечения, трагически не в состоянии воспользоваться им. Не волнуйтесь, я не собираюсь идти s/& &/\ &/на весь мой код:-)... но на этом сайте есть ряд вопросов по улучшению прогнозирования ветвления путем удаления ветвей, и мне пришло в голову, что условные булевы операторы лежат в основе тестовых условий.
Конечно, @StephenC дает фантастический момент, что изгиб вашего кода в странные формы может сделать его менее легким для JITs, чтобы определить общие оптимизации - если не сейчас, то в будущем. И что упомянутый выше очень известный вопрос является особенным, поскольку он подталкивает сложность прогнозирования далеко за пределы практической оптимизации.
Я в значительной степени осознаю, что в большинстве (или почти всех) ситуациях &&
- самая ясная, простая, самая быстрая, лучшая вещь, хотя я очень благодарен людям, которые опубликовали ответы, демонстрирующие это! Мне действительно интересно узнать, есть ли вообще какие-либо случаи в любом случае, когда ответ на вопрос "Может ли &
быть быстрее?" может быть Да...
Обновление 2: (Обращаясь к советам, что вопрос слишком широк. Я не хочу вносить существенные изменения в этот вопрос, потому что он может поставить под угрозу некоторые из приведенных ниже ответов, которые имеют исключительное качество!) Возможно, нужен пример в дикой природе; это из класса Guava LongMath (спасибо, спасибо за @maaartinus за его поиск):
public static boolean isPowerOfTwo(long x) {
return x > 0 & (x & (x - 1)) == 0;
}
Посмотрите, что первый &
? И если вы проверите ссылку, следующий метод называется lessThanBranchFree(...)
, который намекает, что мы находимся на территории отказа от ветвей - и Гуава действительно широко используется: каждый сохраненный цикл заставляет уровни моря заметно уменьшаться. Поэтому давайте ставим вопрос таким образом: это использование &
(где &&
было бы более нормальным) реальную оптимизацию?