2010-03-06 3 views
2

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

Double average = new Double(totalTime/callCount); 

из для цикла?

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); 
} 
+1

Какой компилятор Java? –

+1

Анализ потока на конце компилятора JIT легко скажет вам, что объекты «Double» не выходят нигде, поэтому используются только их содержащиеся значения. Я смею сказать, что вышеприведенную функцию нужно легко оптимизировать в моде, который ищет ОП. –

+0

Я сомневаюсь. Использование примитивного двойника и окончание callCount и totalTime могут помочь, но я все еще сомневаюсь в этом. – Thilo

ответ

0

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

+0

Вы уверены, что компиляторы Java не выполняют даже очевидных оптимизаций? –

+2

@Mike: JIT-компилятор делает. Компилятор от источника к байт-коду не делает этого, но это связано с тем, что оптимизировать не байт-код не так, поскольку он должен проходить JIT в любом случае. –

+2

@Matthew: предупреждение о несоответствии импеданса --- мы с вами думаем о компиляторе JIT, тогда как я думаю, что Фрэнк только думает о джавах. Компилятор JIT - это то место, где происходит оптимизация в тяжелом весе. –

2

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

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

Если вы используете double, однако его гораздо более вероятно оптимизировать (например, используя метод loop-invariant code motion).

+0

Это возможно, что компилятор JIT может обрабатывать определенные типы, особенно в java.lang, как магические. Я был бы удивлен, если бы это не так. –

+0

Как будет оптимизирован примитивный тип? – portoalet

2

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

4

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

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

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

4

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

Смотрите Javadoc для Double.valueOf(double):.

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

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

Однако использование valueOf по-прежнему не является для вас ответом!

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