Пример оптимизации проверки границ Java - PullRequest
2 голосов
/ 03 июля 2011

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

В методе example1 , приведенном ниже, JVM когда-нибудь это выяснит и устранит проверку границ источника index] ссылка?

Является ли example2 лучшей практикой кода?Казалось бы, но в некоторых алгоритмах внутри цикла индекс вне границ является нормальным условием.Таким образом, вы не хотите создавать тонны объектов Exception внутри этого цикла.

public void example1(int [] source, int index) {
    if (index >= 0 && index < source.length)
        System.out.println("Value is " + source[index]);
    else 
        System.out.println("Out of range: " + index);
}

public void example2(int [] source, int index) {
    try {        
        System.out.println("Value is " + source[index]);        
    } catch (IndexOutOfBoundsException exp) {
        System.out.println("Out of range: " + index);
    }
}

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

Ответы [ 2 ]

5 голосов
/ 03 июля 2011

К вашему первому вопросу, в примере1 проверка границ может теоретически быть исключена. Я ожидал бы, что лучшие современные JIT-компиляторы сделают это (например, возможно, путем устранения общего подвыражения при проверке границ при расширении source [index]). Как обычно, это зависит от реализации, поэтому вы не можете полагаться на это. OTOH, даже если проверка границ не устранена, разница будет тривиальной - вы попадаете в уже кэшированную область памяти для source.length и выполняете несколько целочисленных сравнений, поэтому накладные расходы незначительны.

example2 не является хорошей практикой - вы нажимаете исключение, но затем ловите его и продолжаете, как будто ничего не произошло. Если вы не смотрите внимательно stdout, вы можете полностью упустить тот факт, что в вашем коде есть ошибка.

В основном есть две общие "хорошие" возможности в зависимости от того, что вы считаете допустимым входным значением для "индекса":

  1. Значение индекса вне границ ожидается и считается действительным вводом. В в каком случае вы должны проверить и разобраться с этим явно как в примере1. В этом случае вам не нужно создавать какие-либо исключения.

  2. Неожиданный индекс является неожиданным (и поэтому является ошибкой в ​​коде вызова). Ваш код должен вызвать исключение здесь. Если вам нравится, вы можете перехватить и повторно сгенерировать исключение с помощью собственного сообщения, но вы также можете просто разрешить распространению исключения IndexOutOfBounds. Не беспокойтесь о влиянии на производительность этой обработки исключений - вы только что обнаружили ошибку, и поэтому вы хотите, чтобы программа проваливалась так быстро и "громко", как только могла ...

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

Я не понимаю, как индекс, выходящий за границы, может быть нормальным условием.Либо в вашем алгоритме есть ошибка, либо вы неверно подтвердили ввод.И проверка ввода в этом случае заключается в проверке того, что индекс находится в границах.Проверка с помощью if (как в вашем первом фрагменте), очевидно, намного более удобочитаема, чиста и эффективна, чем перехват исключений.

...