Поскольку функция pow
должны реализовать более общий алгоритм, который должен работать на всех случаях (в частности, он должен быть в состоянии поднять до любого рационального показателя представимой double
), в то время как e*e
только простой умножение, которое сводится к одной или двум инструкциям сборки.
По-прежнему, если компилятор достаточно умен, он может автоматически автоматически заменить ваш pow(e, 2.0)
e*e
(ну, на самом деле, в вашем случае он, вероятно, просто выполнит весь расчет во время компиляции).
Просто для удовольствия, я провел несколько тестов: составление следующего кода
#include <math.h>
double pow2(double value)
{
return pow(value, 2.);
}
double knownpow2()
{
double e=2.71828;
return pow(e, 2.);
}
double valuexvalue(double value)
{
return value*value;
}
double knownvaluexvalue()
{
double e=2.71828;
return e*e;
}
с g++ -O3 -c pow.c
(г ++ 4.7.3) и разборкой выхода с objdump -d -M intel pow.o
я получаю:
0000000000000000 <_Z4pow2d>:
0: f2 0f 59 c0 mulsd xmm0,xmm0
4: c3 ret
5: 66 66 2e 0f 1f 84 00 data32 nop WORD PTR cs:[rax+rax*1+0x0]
c: 00 00 00 00
0000000000000010 <_Z9knownpow2v>:
10: f2 0f 10 05 00 00 00 movsd xmm0,QWORD PTR [rip+0x0] # 18 <_Z9knownpow2v+0x8>
17: 00
18: c3 ret
19: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0]
0000000000000020 <_Z11valuexvalued>:
20: f2 0f 59 c0 mulsd xmm0,xmm0
24: c3 ret
25: 66 66 2e 0f 1f 84 00 data32 nop WORD PTR cs:[rax+rax*1+0x0]
2c: 00 00 00 00
0000000000000030 <_Z16knownvaluexvaluev>:
30: f2 0f 10 05 00 00 00 movsd xmm0,QWORD PTR [rip+0x0] # 38 <_Z16knownvaluexvaluev+0x8>
37: 00
38: c3 ret
Итак, когда компилятор уже знал все задействованные значения, он просто выполнял вычисления во время компиляции; и для обоих pow2
и valuexvalue
он выбрал один mulsd xmm0,xmm0
(т. е. в обоих случаях он сводится к умножению значения с самим собой в одной команде сборки).
Потому что умножение 'double' является дешевым, делая то, что' pow' does not (вычисляет корни для десятичных степеней). –
Кроме того, «компиляция с той же скоростью»! = «Работает с одинаковой скоростью». Компиляция - это * очень * отдельный процесс от фактического запуска кода. –
@ RichardJ.RossIII: Я думаю, что «десятичным» вы на самом деле называете «дробным»; например, 'pow (1.2, 3.4)', что не может быть сделано простой последовательностью умножений. –