Обмен переменными с вспомогательной переменной и без нее - что быстрее?

Думаю, вы все слышали о "проблеме подмены"; в SO много вопросов по этому поводу. Версия замены без использования третьей переменной часто считается более быстрой, поскольку, ну, у вас на одну переменную меньше. Я хотел узнать, что происходит за занавесками, и написал следующие две программы:

int main () {
    int a = 9;
    int b = 5;
    int swap;

    swap = a;
    a = b;
    b = swap;

    return 0;
}

и версию без третьей переменной:

int main () {
    int a = 9;
    int b = 5;

    a ^= b;
    b ^= a;
    a ^= b;

    return 0;
}

Я сгенерировал ассемблерный код с помощью clang и получил следующее для первой версии (которая использует третью переменную):

...
Ltmp0:
    movq   %rsp, %rbp
Ltmp1:
    movl   $0, %eax
    movl   $0, -4(%rbp)
    movl   $9, -8(%rbp)
    movl   $5, -12(%rbp)
    movl   -8(%rbp), %ecx
    movl   %ecx, -16(%rbp)
    movl   -12(%rbp), %ecx
    movl   %ecx, -8(%rbp)
    movl   -16(%rbp), %ecx
    movl   %ecx, -12(%rbp)
    popq   %rbp
    ret
Leh_func_end0:
...

и следующее для второй версии (которая не использует третью переменную):

...
Ltmp0:
    movq    %rsp, %rbp
Ltmp1:
    movl   $0, %eax
    movl   $0, -4(%rbp)
    movl   $9, -8(%rbp)
    movl   $5, -12(%rbp)
    movl   -12(%rbp), %ecx
    movl   -8(%rbp), %edx
    xorl   %ecx, %edx
    movl   %edx, -8(%rbp)
    movl   -8(%rbp), %ecx
    movl   -12(%rbp), %edx
    xorl   %ecx, %edx
    movl   %edx, -12(%rbp)
    movl   -12(%rbp), %ecx
    movl   -8(%rbp), %edx
    xorl   %ecx, %edx
    movl   %edx, -8(%rbp)
    popq   %rbp
    ret
Leh_func_end0:
...

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

Какая из приведенных выше версий замены переменной быстрее и занимает меньше памяти?

5
задан mirabilos 22 December 2015 в 15:56
поделиться