Я провел несколько экспериментов с циклами в Android и был озадачен результатами.
В прошлом я где-то читал, что (в C ++ ??), если перевести этот цикл:
for(int i = 0; i != Integer.MAX_VALUE; i++)
{
// Do something
}
... в этот цикл:
for(int i = threshold; --i >= 0; )
{
// Do the same
}
Вы можете получить значительное увеличение производительности, поскольку второй вариант будет генерировать сравнение с нулем, которое из-за архитектуры процессоров намного быстрее, чем сравнение между двумя ненулевыми значениями в первом цикле.
Я хотел посмотреть, так ли это в Android, поэтому я начал с написания кода и использовал DEX, чтобы посмотреть на сгенерированный байт-код Dalvik, чтобы убедиться, что оптимизация компилятора не происходит.
Действительно, это были результаты:
0003dc: 1201 |000e: const/4 v1, #int 0 // #0
0003de: 1402 ffff ff7f |000f: const v2, #float NaN // #7fffffff
0003e4: 3321 5000 |0012: if-ne v1, v2, 0062 // +0050
000434: 1401 ffff ff7f |003a: const v1, #float NaN // #7fffffff
00043a: d801 01ff |003d: add-int/lit8 v1, v1, #int -1 // #ff
00043e: 3b01 2800 |003f: if-gez v1, 0067 // +0028
(в данном случае это не имеет значения код 0062 и 0067, так как я просто обеспокоен тем, что сам цикл).
Хорошо, но мы можем ясно видеть, что компилятор / транслятор не вводит оптимизацию, поскольку оба синтаксиса цикла имеют разный сгенерированный байт-код.
Теперь, когда контекст установлен и я доказал, что было бы полезно продолжить тестирование, пришло время для вопроса:
«После того, как я профилировал приведенный выше код и выяснил, что независимо от порядка выполнения цикла первый всегда занимает больше времени, чем второй, чего мне здесь не хватает?»
Что-то вроде JIT-компиляции делает некоторую оптимизацию для меня?
Я ожидаю, что оба цикла ведут себя по-разному, поскольку сгенерированный байт-код не совпадает.
Большое спасибо за любые усилия, чтобы просветить меня по этому вопросу.