оптимизация компилятора Java - PullRequest
2 голосов
/ 06 марта 2010

Достаточно ли умен Java компилятор, чтобы оптимизировать цикл ниже, извлекая

Double average = new Double( totalTime / callCount ); 

из цикла for?

public double computeSD( Set values, int callCount, long totalTime ) {
  double diffs = 0.0d; 
  for( Iterator i=values.iterator(); i.hasNext(); ) {
    double value = ( ( Double )i.next() ).doubleValue(); 
    Double average = new Double( totalTime / callCount ); 
    diffs += ( value – average.doubleValue() ) * ( value – average.doubleValue() );
  } 
  double variance = diffs / callCount;
  return Math.sqrt( variance );
}

Ответы [ 5 ]

4 голосов
/ 25 сентября 2012

Java не будет и не сможет извлечь его из цикла.Любое использование ключевого слова «new» всегда приводит к созданию нового объекта.Было бы лучше использовать Double.valueOf()

См. Javadoc для Double.valueOf(double):

"Возвращает экземпляр Double, представляющий указанное двойное значение. Если новый экземпляр Doubleобязательно, этот метод обычно следует использовать вместо конструктора Double (double), так как этот метод, вероятно, даст значительно лучшую производительность в пространстве и времени за счет кэширования часто запрашиваемых значений. "этот метод будет возвращать один и тот же объект каждый раз, тем самым уменьшая количество создаваемых объектов и повышая производительность.

Однако использование valueOf все еще не ответ для вас!* по-прежнему является вызовом метода, и вызовы метода не оптимизируются.Он будет вызывать valueOf каждую итерацию цикла.Просмотрите ваш метод и посчитайте вызовы метода.Сейчас это 6, включая hasNext и new Double, что похоже на вызов метода.Все это будет происходить каждый раз, и никакая оптимизация Java не изменит это.Лучше рефакторинг, чтобы удалить как можно больше вызовов методов из цикла.

4 голосов
/ 06 марта 2010

Ничто не мешает компилятору байт-кода (java-> bytecode) выполнить оптимизацию.Когда я работал в Symantec и разработал Java IDE, при написании компилятора мы попытались внести некоторые оптимизации в наш компилятор, но сказали, что никто (во внешнем мире), похоже, не заинтересован, и акцент был сделан на Just In Time (JIT)компилятор, который примерно такой же, как HotSpot в современных виртуальных машинах Sun.

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

Итак, компилятор байт-кода source->, вероятно, не оптимизирует его, но, вероятно, виртуальная машина.Если у вас есть что-то вроде Android, то он, вероятно, не выполняет оптимизацию во время выполнения.

2 голосов
/ 06 марта 2010

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

Я не думаю, что какой-либо текущий компилятор может оптимизировать это. Чтобы это было оптимизировано, компилятору нужно сказать, что некоторые классы имеют специальные свойства (что может быть опасным предложением, учитывая, что вещи могут измениться в будущем). То есть компилятору нужно сообщить специфику API. Это нельзя оптимизировать только на уровне языка.

Однако, если вы используете double, вероятность его оптимизации будет гораздо выше (например, с использованием метода инвариантного кода движения ).

2 голосов
/ 06 марта 2010

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

0 голосов
/ 06 марта 2010

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

...