2015-03-04 2 views
0

Ниже приведен код для метода объекта, который поддерживает список типов (IType[] types) в массиве, а также поле, в котором хранится количество ненулевых типов в массиве (int typeCount). То, что должен сделать метод, это resolve все типы в списке (resolve либо возвращает тип, который он вызывал, либо другой IType). Я теперь интересно, какие из следующих реализаций лучше:Обновление массива Java

for (int i = 0; i < this.typeCount; i++) 
{ 
    this.types[i] = this.types[i].resolve(markers, context); 
    // vs 
    IType t1 = this.types[i]; 
    IType t2 = t1.resolve(markers, context); 
    if (t1 != t2) 
    { 
     this.types[i] = t2; 
    } 
} 

Обратите внимание, что эта модель встречается во многих местах на протяжении всего проекта, многие из которых можно считать шаблонными.

+0

Понятно из текста, что некоторые элементы массива могут быть «null». Это означает, что перед вызовом 'resolve' вы должны проверить' null'. И 'i

+0

Пока 'i Clashsoft

ответ

1

Другие ответы на это не совсем правильны.

Правильный ответ, скорее всего, тот же, но он зависит от JVM, а также от аргументов, переданных команде java.

JVM будет встроить и оптимизировать код в значительной степени, поэтому, даже если вы используете локальные переменные, это не значит, что код будет выполнен, поскольку он написан. В конце дня JVM выполнит операции стека в соответствии с инструкциями байткода. Также JVM может выполнять спекулятивное выполнение, так что условие if может быть вычислено до достижения и имеет почти 0 эффект производительности.

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

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

+0

Ветвление может быть дорогостоящим - я только что проверил тест по второму методу с массивом в 100 ints. Если ветка всегда истинна (t1 == t2), она выполняется в 45 нс, если она равна 75% времени, когда она работает в 230 нс, если она равна 50% времени (наихудший сценарий), она работает в 310 нс. Поэтому, говоря, что условие if не имеет эффекта производительности, является неточным. – assylias

+0

Если вы не предоставите точную информацию о том, как вы ее протестировали, то, что вы сказали, может и не может быть правдой. – Crazyjavahacking

+0

Я использовал jmh, но результат ожидается - см. Например: http://stackoverflow.com/a/11227902/829571 – assylias

0

В случае сомнений измерьте!

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

В случае сомнений измерьте!

0

Что касается производительности, мы можем посмотреть на код и судить, что первое однолинейное решение выполняет всю работу в одной строке, что заставляет его повторять шаблон n раз. В зависимости от количества элементов в массиве цикл будет запускать O (n) раз. Теперь в отношении второго решения следующая инструкция: Load, Assign (Request storage), Assign, Compare, Assign if. Таким образом, количество заявлений атомов увеличивается на справедливую сумму. Если много объектов присутствует, я бы пошел с первым решением. Кроме того, когда вы сравниваете объекты, я бы использовал .equals() для сравнения, который также является другим методом учета.

+0

Я не использую equals здесь, потому что я просто проверяю, нужно ли обновлять массив, но в остальном я вижу, что первый метод должен быть немного быстрее (если мне не нужен «t1» для чего-то еще). – Clashsoft

0

Правильный ответ: зависит от.

Пример, подобный вашему, рассматривается в статье cool presentation Сергеем Куксенко на счетчиках аппаратной производительности (слайды 45-49). Этот пример показывает, что ответ противоположно отличается в зависимости от длины массива.

На аппаратном уровне слишком много факторов (неверное предсказание ветвления, промахи кэша L1 и т. Д.), Поэтому вы не можете знать заранее, пока не будете измерять, используя реальный набор данных.