Я написал простую функцию С++ для проверки оптимизации компилятора:
bool f1(bool a, bool b) {
return !a || (a && b);
}
После этого я проверил эквивалент в Rust:
fn f1(a: bool, b: bool) -> bool {
!a || (a && b)
}
Я использовал godbolt, чтобы проверить выход ассемблера.
Результат кода С++ (скомпилированный clang с флагом -O3) выглядит следующим образом:
f1(bool, bool): # @f1(bool, bool)
xor dil, 1
or dil, sil
mov eax, edi
ret
И результат эквивалента Rust намного длиннее:
example::f1:
push rbp
mov rbp, rsp
mov al, sil
mov cl, dil
mov dl, cl
xor dl, -1
test dl, 1
mov byte ptr [rbp - 3], al
mov byte ptr [rbp - 4], cl
jne .LBB0_1
jmp .LBB0_3
.LBB0_1:
mov byte ptr [rbp - 2], 1
jmp .LBB0_4
.LBB0_2:
mov byte ptr [rbp - 2], 0
jmp .LBB0_4
.LBB0_3:
mov al, byte ptr [rbp - 4]
test al, 1
jne .LBB0_7
jmp .LBB0_6
.LBB0_4:
mov al, byte ptr [rbp - 2]
and al, 1
movzx eax, al
pop rbp
ret
.LBB0_5:
mov byte ptr [rbp - 1], 1
jmp .LBB0_8
.LBB0_6:
mov byte ptr [rbp - 1], 0
jmp .LBB0_8
.LBB0_7:
mov al, byte ptr [rbp - 3]
test al, 1
jne .LBB0_5
jmp .LBB0_6
.LBB0_8:
test byte ptr [rbp - 1], 1
jne .LBB0_1
jmp .LBB0_2
Я также пробовал с опцией -O
, но вывод пуст (удаленная неиспользуемая функция).
Я намеренно НЕ использую какую-либо библиотеку, чтобы поддерживать чистоту вывода. Обратите внимание, что как clang
, так и rustc
используют LLVM в качестве бэкэнд. Что объясняет эту огромную разницу в производительности? И если это проблема только с отключенным оптимизатором, как я могу увидеть оптимизированный вывод из rustc
?