Все ответы с самым высоким рейтингом на самом деле не являются окончательными "фактами" ... это люди, которые спекулируют!
Вы можете окончательно точно знать , какой код требует меньше сборочных инструкций для выполнения, потому что вы можете посмотреть на выходную сборку, сгенерированную компилятором, и увидеть, которая выполняется в меньших сборочных инструкциях!
Вот код c, который я скомпилировал с флагами "gcc -std = c99 -S -O3 lookingAtAsmOutput.c":
#include <stdio.h>
#include <stdlib.h>
void swap_traditional(int * restrict a, int * restrict b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void swap_xor(int * restrict a, int * restrict b)
{
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
int main() {
int a = 5;
int b = 6;
swap_traditional(&a,&b);
swap_xor(&a,&b);
}
Вывод ASM для swap_traditional () требует >>> 11 <<< инструкций (не включая «уйти», «ret», «размер»): </p>
.globl swap_traditional
.type swap_traditional, @function
swap_traditional:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl 12(%ebp), %ecx
pushl %ebx
movl (%edx), %ebx
movl (%ecx), %eax
movl %ebx, (%ecx)
movl %eax, (%edx)
popl %ebx
popl %ebp
ret
.size swap_traditional, .-swap_traditional
.p2align 4,,15
ASM-вывод для swap_xor () занимает >>> 11 <<< инструкции, не включающие в себя «уход» и «ret»: </p>
.globl swap_xor
.type swap_xor, @function
swap_xor:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %ecx
movl 12(%ebp), %edx
movl (%ecx), %eax
xorl (%edx), %eax
movl %eax, (%ecx)
xorl (%edx), %eax
xorl %eax, (%ecx)
movl %eax, (%edx)
popl %ebp
ret
.size swap_xor, .-swap_xor
.p2align 4,,15
Сводка выходных данных сборки:
swap_traditional () занимает 11 инструкций
swap_xor () занимает 11 инструкций
Вывод:
Оба метода используют одинаковое количество инструкций для выполнения и поэтому имеют примерно одинаковую скорость на этой аппаратной платформе.
Извлеченный урок:
Когда у вас есть небольшие фрагменты кода, просмотр вывода asm полезен для быстрой итерации вашего кода и получения самого быстрого кода (т.е. с наименьшим количеством инструкций). И вы можете сэкономить время, даже если вам не нужно запускать программу для каждого изменения кода. Вам нужно только запустить изменение кода в конце с помощью профилировщика, чтобы показать, что изменения кода происходят быстрее.
Я часто использую этот метод для тяжелого кода DSP, которому нужна скорость.