Java с использованием логических операторов вместо if-else, если для возврата - PullRequest
2 голосов
/ 09 июля 2011

У меня есть следующий код в методе equals.

public boolean equals(Object o){
    if (o == null) return false;
    if (o == this) return true;
    if (!(o instanceof Vertex)) return false;
    return ((Vertex) o).label().equals(label);
}

Моя IDE выделяет оператор if и хочет, чтобы я делал это в основном

public boolean equals(Object o){
    return (o != null) && ((o==this) || ((o instanceof Vertex) && ((Vertex) o).label().equals(label);
}

Мне сказали, что компилятор, как правило, достаточно умен, чтобы оптимизировать, и что в общем случае код должен быть читаемым. Очевидно, что второй пример кода не так легко читается, как первый. Моя IDE просто раздражает или есть какая-то реальная заслуга в производительности, чтобы сделать это таким образом?

Ответы [ 6 ]

2 голосов
/ 09 июля 2011

Во-первых, оптимизируйте, только если вы знаете, , что это узкое место, иначе код для удобства чтения.

Вы можете проверить байт-код, чтобы увидеть, но я подозреваю, что они довольно близки, если не совсем одинаковы.Даже если есть небольшие различия в байт-коде, я видел, как JIT-компилятор оптимизировал вещи там, где нет никакой разницы.Вы всегда можете сделать тесты производительности, чтобы быть уверенным.

1 голос
/ 10 июля 2011

Преимущества производительности, предлагаемые вашей IDE, практически отсутствуют.Кроме того, вы правы в том, что JVM (не только компилятор) может выполнять множество оптимизаций.

Как указывали другие, попробуйте достичь читабельности.Код, который вы пишете, читается людьми и компилируется, модифицируется и оптимизируется компилятором Java и виртуальной машиной.

Кстати.краткий совет: ваш код можно немного оптимизировать следующим образом (исключая условие равенства null, поскольку o гарантированно будет экземпляром Vertex после второго условия):

public boolean equals(Object o){
    if (o == this) return true;
    if (!(o instanceof Vertex)) return false;
    return ((Vertex) o).label().equals(label);
}
1 голос
/ 09 июля 2011

Большинство IDE являются настраиваемыми и позволяют указывать виды предупреждений о стилях, которые он выводит.Вы правы в том, что делать то, что предлагает компилятор, с точки зрения генерируемого кода, не имеет смысла.Компиляторы действительно должны быть в состоянии оптимизировать такие вещи.

0 голосов
/ 10 июля 2011

Почему бы не проверить производительность самостоятельно?Вот пример:

public static long timeIt(Runnable runnable) {
    long start = System.nanoTime();
    runnable.run();
    long end = System.nanoTime();
    return end - start;
}

будет рассчитывать метод запуска для вас.Таким образом, вы можете назвать это так:

timeIt(new Runnable() { public void run() { OPERATION_TO_BE_TIMED; }})
0 голосов
/ 10 июля 2011

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

public boolean equals(Object o){
    return o == null || !(o instance of Vertex) ? false :
       o == this ? true :
       ((Vertex) o).label().equals(label);
}

Это должно быть доступно для чтения.

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

0 голосов
/ 09 июля 2011

Не пытайтесь использовать умный компилятор.Вы пишете код для человека, чтобы читать.Пусть компилятор беспокоится о преобразовании его в машиночитаемый формат.

...