Думаю, вы все слышали о «проблеме свопа»; 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:
...
Второй длиннее, но я мало знаю о ассемблере, поэтому понятия не имею, означает ли это, что он медленнее, поэтому я хотел бы услышать мнение кого-то более знающего об этом.
Какая из приведенных выше версий свопинга переменных быстрее и требует меньше памяти?