Какой способ установки чего-либо, когда он нулевой, быстрее? - PullRequest
2 голосов
/ 21 июля 2011

Что быстрее в Java и почему?

try {
  object.doSomething()
} catch (NullPointerException e) {
  if (object == null) {
    object = new .....;
    object.doSomething();
  } else throw e;
}

или

if (object == null) {
  object = new .....;
}
object.doSomething();

а почему?

Код будет вызываться часто, и object - это всего лишь null при первом вызове, поэтому не учитывайте стоимость брошенного NPE (это происходит только один раз).

P.S. Я знаю, что второе лучше из-за простоты, читабельности и т. Д., И Я бы наверняка пошел на это в реальном программном обеспечении . Я знаю все о зле преждевременной оптимизации, не нужно об этом упоминать. Мне просто интересно узнать об этих маленьких деталях.

Ответы [ 7 ]

9 голосов
/ 21 июля 2011

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

это чисто анекдотично, но все микробенчмаркинг, который я когда-либо делал, показал, что использование исключений для потока управления не будеттакой же производительный, как условные, хотя, вероятно, это невозможно поддержать как обобщение, и JVM очень хорошо умеет оптимизировать подобные вещи, так что YMMV.

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

Независимо от скорости, первый способ не является хорошей практикой программирования. Например, что если object не был нулевым, но object.doSomething() привел к NullPointerException?

Это одна из причин, по которой вам не следует использовать исключения для управления потоком программ!

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

Забудьте о скорости - посмотрите на размер кода в первом фрагменте по сравнению со вторым.

Является ли более простой вариант лучшим? Легче читать, занимает меньше места и т. Д. Сначала нужно стремиться к простоте кода, а затем беспокоиться о скорости, как только вы измерили что-то медленное.

Кроме того, подумайте о том, что среда выполнения должна сделать, чтобы определить, что ей нужно выбросить NullPointerException - она ​​должна проверить, является ли текущая ссылка null. Поэтому даже без измерения логично было бы иметь смысл, что выполнить проверку самостоятельно проще, чем оставлять на усмотрение JRE, чтобы проверка и создала NullPointerException и раскручивание стек.

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

Проверьте Информационный бюллетень специалистов по Java - выпуск 187 Стоимость создания исключений для получения некоторых интересных внутренних деталей.

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

Чтобы ответить на ваш вопрос, версия 1 намного медленнее, когда она взрывается, потому что создание Исключений довольно дорого, но это не быстрее, чем версия 2, потому что JVM должна сама выполнить проверку нуля в любом случае , чтобы вы ' не сохранять в любое время. Компилятор, скорее всего, оптимизирует код, поэтому он все равно не будет быстрее.

Также исключения должны быть зарезервированы для исключительных. Начальное состояние null не является исключительным.

Используйте ленивый шаблон инициализации:

SomeClass getIt() {
    if (it == null)
        it = new SomeClass();
    return it;
}

...
getIt().someMethod();
0 голосов
/ 21 июля 2011

Я хочу сказать, что второе решение быстрее. Не потому, что я эксперт по JIT или VM, а потому, что имеет смысл, что одна процедура на уровне сборки ветвь-если-равно быстрее, чем поиск объекта в памяти, определяя, что он нулевой (тот же тест, я предположим), выбрасывая исключение и, возможно, портя стек.

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

выброшенное исключение (первый пример) почти всегда медленнее, чем обычный код потока управления (второй пример)

, что, кроме второго, намного чище и легче для понимания

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