Подтвердить что ты не робот

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.
  */

Как это проблема производительности? Разве компилятор не уменьшит их до одного и того же?

В более широком смысле, какая хорошая стратегия для этого? Я могу запускать тесты, но меня больше интересует анализ любых различий в скомпилированном коде. Однако я не знаю, какие инструменты использовать и т.д.

4b9b3361

Ответ 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 равна! Таким образом, производительность байт-кодов тоже должна быть одинаковой.