При вычислении чисел Фибоначчи распространенным методом является сопоставление пары чисел от (a, b)
до (b, a + b)
несколько раз. Обычно это можно сделать, определив третью переменную c
и выполнив обмен. Однако я понял, что вы можете сделать следующее, избегая использования третьей целочисленной переменной:
b = a + b; // b2 = a1 + b1
a = b - a; // a2 = b2 - a1 = b1, Ta-da!
Я ожидал, что это будет быстрее, чем использование третьей переменной, поскольку, по моему мнению, этот новый метод должен учитывать только две области памяти.
Итак, я написал следующие программы на C, сравнивающие процессы. Они имитируют вычисление чисел Фибоначчи, но будьте уверены, я знаю, что они не будут вычислять правильные значения из-за ограничений размера.
(Примечание: теперь я понимаю, что было необязательно делать n
a long int
, но я буду сохранять его таким, как есть, потому что именно так я его сначала скомпилировал)
Файл: PlusMinus.c
// Using the 'b=a+b;a=b-a;' method.
#include <stdio.h>
int main() {
long int n = 1000000; // Number of iterations.
long int a,b;
a = 0; b = 1;
while (n--) {
b = a + b;
a = b - a;
}
printf("%lu\n", a);
}
Файл: ThirdVar.c
// Using the third-variable method.
#include <stdio.h>
int main() {
long int n = 1000000; // Number of iterations.
long int a,b,c;
a = 0; b = 1;
while (n--) {
c = a;
a = b;
b = b + c;
}
printf("%lu\n", a);
}
Когда я запускаю их с GCC (оптимизация не включена), я замечаю постоянную разницу в скорости:
$ time ./PlusMinus
14197223477820724411
real 0m0.014s
user 0m0.009s
sys 0m0.002s
$ time ./ThirdVar
14197223477820724411
real 0m0.012s
user 0m0.008s
sys 0m0.002s
Когда я запускаю два с GCC с -O3
, выходные данные сборки равны. (Я подозреваю, что у меня было смещение подтверждения, когда я утверждал, что один из них превосходил другой в предыдущих изменениях.)
Проверяя сборку для каждого, я вижу, что PlusMinus.s
на самом деле имеет на одну инструкцию меньше, чем ThirdVar.s
, но работает стабильно медленнее.
Вопрос
Почему возникает эта разница во времени? Не только вообще, но и почему мой метод сложения / вычитания медленнее вопреки моим ожиданиям?