O Groovy Гуру,
Этот фрагмент кода работает примерно за 1 секунду
for (int i in (1..10000000)) {
j = i;
}
в то время как этот занимает почти 9 секунд
for (int i = 1; i < 10000000; i++) {
j = i;
}
Почему так?
O Groovy Гуру,
Этот фрагмент кода работает примерно за 1 секунду
for (int i in (1..10000000)) {
j = i;
}
в то время как этот занимает почти 9 секунд
for (int i = 1; i < 10000000; i++) {
j = i;
}
Почему так?
Ok. Вот мой вопрос: почему?
Если вы конвертируете оба скрипта в байт-код, вы заметите, что
ScriptBytecodeAdapter.compareLessThan → ScriptBytecodeAdapter.compareTo → DefaultTypeTransformation.compareTo
Существуют другие классы в пакете обработки типов, который реализует метод compareTo специально для математических типов данных, не уверен, почему они не используются (если они не используются)
Я подозреваю, что причина в том, что вторая петля занимает больше времени. Опять же, пожалуйста, поправьте меня, если я ошибаюсь или что-то не хватает...
В своем тестировании, прежде чем принимать меры, обязательно "согреть" JVM, иначе вы можете запустить различные действия по запуску на платформе (загрузка классов, компиляция JIT). Выполняйте тесты много раз подряд. Кроме того, если вы сделали второй тест, пока собирался сбор мусора, это может повлиять. Попробуйте запустить каждый из тестов 100 раз и распечатать время после каждого теста и посмотреть, что это говорит вам.
Если вы можете устранить потенциальные артефакты из времени запуска, как предлагает Джим, тогда я бы поставил под сомнение, что цикл Java для цикла в Groovy не так хорошо реализован, как исходный стиль Groovy для цикла. Он был добавлен только с версии 1.5 после запросов пользователя, поэтому, возможно, его реализация была немного запоздалой.
Вы взглянули на байт-код, сгенерированный для ваших двух примеров, чтобы увидеть, есть ли какие-либо различия? Здесь обсуждалась Groovy производительность здесь, в которой один из комментариев (из одной "johnchase" ) говорит следующее:
Интересно, относится ли разница, связанная с тем, как Groovy использует числа (примитивы) - поскольку она обертывает все примитивы в своих эквивалентных классах оболочки Java (int → Integer), Id предсказывает, что это немного замедлит работу, Я заинтересован в том, чтобы производительность Java-кода составляла 10 000 000, используя классы-оболочки вместо int.
Итак, возможно, исходный цикл Groovy for не страдает от этого? Просто размышления с моей стороны действительно.