Java 7 сортировка "оптимизация"
В Java6 как quicksort, так и mergesort были использованы в Arrays#sort
для примитивных и объектных массивов соответственно. В Java7 они оба изменились, на DualPivotQuicksort и Timsort.
В источнике для новой быстрой сортировки в нескольких местах появляется следующий комментарий (например, строка 354):
/*
* Here and below we use "a[i] = b; i++;" instead
* of "a[i++] = b;" due to performance issue.
*/
Как это проблема производительности? Разве компилятор не уменьшит их до одного и того же?
В более широком смысле, какая хорошая стратегия для этого? Я могу запускать тесты, но меня больше интересует анализ любых различий в скомпилированном коде. Однако я не знаю, какие инструменты использовать и т.д.
Ответы
Ответ 1
Это только ответ на общий вопрос.
Вы можете посмотреть на байт-код и попытаться понять различия. То есть вы можете написать себе простой пример, используя как a[i] = b; i++;
, так и a[i++] = b;
и посмотреть, в чем разница.
Самый простой способ показать байт-код - это программа javap
(должна быть включена в JDK). Скомпилируйте код с помощью javac SomeFile.java
и запустите javap в коде: javap -c SomeFile
(ключ -c сообщает javap выводить байт-код для каждого метода в файле).
Если вы используете eclipse, вы также можете попробовать этот.
Ответ 2
Я написал 2 метода test1 и test2 и добавил основную часть скомпилированного байтового кода (Java 1.6 на Snow Leopard) в качестве комментария:
/*
* 14 iload_1 [b] -> load value from address 1 to sack
* 15 iastore -> store value from stack into int array
* 16 iinc 3 1 [i] -> int increment value of address 3
* 19 iinc 3 1 [i] -> int increment value of address 3
*/
public void test1() {
int b = 0;
int a[] = new int[10];
for (int i=0; i<10; i++) {
a[i] = b;
i++;
}
}
/*
* 14 iinc 3 1 [i] -> increment value of address 3
* 17 iload_1 [b] -> load value from address 1 to stack
* 18 iastore -> store value from stack into int array
* 19 iinc 3 1 [i] -> increment value of address 3
*/
public void test2() {
int b = 0;
int a[] = new int[10];
for (int i=0; i<10; i++) {
a[i++] = b;
}
}
Порядок опций inc
отличается. Но сумма операций обоих методов test1 и test2 равна! Таким образом, производительность байт-кодов тоже должна быть одинаковой.
Ответ 3
Существует способ, который позволяет вам видеть инструкции процессора генерируемые движком hotspot.