获取斐波那契数列中每个数字的 运行 次
Get run-time of each number in a Fibonacci sequence
#include <stdio.h>
#include <time.h>
void printFibonacci(int n) {
static int n1 = 0, n2 = 1, n3;
if (n > 0) {
n3 = n1 + n2;
n1 = n2;
n2 = n3;
printf("%d ", n3);
printFibonacci(n - 1);
}
}
int main() {
int n;
struct timespec start, stop;
double total_time;
clock_gettime(CLOCK_REALTIME, &start);
printf("Enter the number of elements: ");
scanf("%d", &n);
printf("Fibonacci Series: ");
printf("%d %d ", 0, 1);
printFibonacci(n - 2);
clock_gettime(CLOCK_REALTIME, &stop);
total_time = (stop.tv_sec - start.tv_sec) * 1e9;
total_time = (total_time + (stop.tv_nsec - start.tv_nsec)) * 1e-9;
printf("\nTime taken for each sequence: %lf", total_time);
return 0;
}
上面这个C程序让用户输入一个整数,然后程序会输出斐波那契数列。我想要做的是将斐波那契数列中每个数字的 运行 时间精确到纳秒。到目前为止,我的尝试是使用 clockgettime()
函数来获取 fibonacci
函数的开始和停止时间。但是,这只会输出函数花费的总时间,而不是每个单独序列花费的时间。我将如何修复此代码以便获取每个单独的序列时间?
例如,如果用户输入 12,我想要的输出将如下所示,其中显示每个序列时间:
Enter the number of elements: 12
Fibonacci Series: 0 1 1 2 3 5 8 13 21 34 55 89
Time taken for each sequence: 0.1023, 0.2024, 0.3025, 0.7024, 0.9323, 0.12023, 0.78923, 0.6723, 0.12323, 0.9033, 0.34523, 0.123423
好像您在主程序上使用了时钟,这意味着它确实如您所说计算了函数的总运行时间。
为了计算您完成一个序列所花费的时间,您应该考虑移动
clock_gettime(CLOCK_REALTIME, &start);
并且:
clock_gettime(CLOCK_REALTIME, &stop);
total_time = (stop.tv_sec - start.tv_sec) * 1e9;
total_time = (total_time + (stop.tv_nsec - start.tv_nsec)) * 1e-9;
对于 printFibonacci 的开始和结束,恭敬地,在这种情况下,在每次递归中,您将看到序列发生的确切时间。
按照问题中的编码,计算整个序列的时间,包括用户输入数字所花费的时间和 printf
输出值所花费的时间。这是没有意义的。
此外,您将秒数乘以 109,然后将纳秒数也除以 109:您应该做一个或另一个,但不能同时做。
如果你想为每个数字的计算计时,你应该在前 2 个数字相加之前检索时钟,并在 3 个赋值之后立即重新检索时钟。尝试对这样一个简单的操作计时是相当困难的:clock_gettime()
不是正确的工具,您更有可能只测量 clock_gettime
的开销,CLOCK_REALTIME
的不精确性,可能当您测量 CLOCK_REALTIME
而不是当前进程的运行时时,异步进程会中断您的程序。您可能应该改用 clock()
,但测量值可能微不足道。
中间时间应存储在 static
数组中,以便 main
打印它们。
这是修改后的版本:
#include <stdio.h>
#include <time.h>
#define MAX_TIMINGS 100
static double timings[MAX_TIMINGS];
static int timing_index = 2;
void printFibonacci(int n) {
static int n1 = 0, n2 = 1, n3;
if (n > 0) {
struct timespec start, stop;
clock_gettime(CLOCK_REALTIME, &start);
n3 = n1 + n2;
n1 = n2;
n2 = n3;
clock_gettime(CLOCK_REALTIME, &stop);
if (timing_index < MAX_TIMINGS) {
timings[n] = (stop.tv_sec - start.tv_sec) * 1e9 +
(stop.tv_nsec - start.tv_nsec);
}
printf("%d ", n3);
printFibonacci(n - 1);
}
}
int main() {
int i, n;
double total_time = 0;
printf("Enter the number of elements: ");
scanf("%d", &n);
printf("Fibonacci Series: ");
printf("%d %d ", 0, 1);
printFibonacci(n - 2);
printf("\n");
printf("Time taken for each number:");
for (i = 0; i <= n; i++) {
printf(" %.0fns", timings[i]);
total_time += timings[i];
}
printf("\n");
printf("Total time: %.0fns\n", total_time);
return 0;
}
输出:
Enter the number of elements: 20
Fibonacci Series: 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
Time taken for each number: 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns
Total time: 0ns
毫不奇怪,所有时间都是空的。测量顺序生成器的每个数字的时间是没有意义的。
相反,时间对于经典的递归实现很重要,其中涉及许多递归调用,即使是中等大的参数。
这里有一个比较经典的例子:
#include <stdio.h>
#include <time.h>
unsigned long long fib(int n) {
if (n < 2)
return n;
else
return fib(n - 1) + fib(n - 2);
}
int main() {
int i, n;
double total_time = 0;
printf("Enter the number of elements: ");
if (scanf("%d", &n) != 1)
return 1;
double timings[n + 1];
printf("Fibonacci Series:");
for (i = 0; i <= n; i++) {
struct timespec start, stop;
unsigned long long res;
clock_gettime(CLOCK_REALTIME, &start);
res = fib(i);
clock_gettime(CLOCK_REALTIME, &stop);
timings[i] = ((stop.tv_sec - start.tv_sec) * 1e9 +
(stop.tv_nsec - start.tv_nsec));
printf(" %llu", res);
}
printf("\n");
printf("Time taken for each number:");
for (i = 0; i <= n; i++) {
printf(" %.0fns", timings[i]);
total_time += timings[i];
}
printf("\n");
printf("Total time: %.0fns\n", total_time);
return 0;
}
输出:
Enter the number of elements: 20
Fibonacci Series: 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
Time taken for each number: 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 1000ns 0ns 1000ns 1000ns 2000ns 5000ns 6000ns 10000ns 18000ns 38000ns 69000ns
Total time: 151000ns
#include <stdio.h>
#include <time.h>
void printFibonacci(int n) {
static int n1 = 0, n2 = 1, n3;
if (n > 0) {
n3 = n1 + n2;
n1 = n2;
n2 = n3;
printf("%d ", n3);
printFibonacci(n - 1);
}
}
int main() {
int n;
struct timespec start, stop;
double total_time;
clock_gettime(CLOCK_REALTIME, &start);
printf("Enter the number of elements: ");
scanf("%d", &n);
printf("Fibonacci Series: ");
printf("%d %d ", 0, 1);
printFibonacci(n - 2);
clock_gettime(CLOCK_REALTIME, &stop);
total_time = (stop.tv_sec - start.tv_sec) * 1e9;
total_time = (total_time + (stop.tv_nsec - start.tv_nsec)) * 1e-9;
printf("\nTime taken for each sequence: %lf", total_time);
return 0;
}
上面这个C程序让用户输入一个整数,然后程序会输出斐波那契数列。我想要做的是将斐波那契数列中每个数字的 运行 时间精确到纳秒。到目前为止,我的尝试是使用 clockgettime()
函数来获取 fibonacci
函数的开始和停止时间。但是,这只会输出函数花费的总时间,而不是每个单独序列花费的时间。我将如何修复此代码以便获取每个单独的序列时间?
例如,如果用户输入 12,我想要的输出将如下所示,其中显示每个序列时间:
Enter the number of elements: 12
Fibonacci Series: 0 1 1 2 3 5 8 13 21 34 55 89
Time taken for each sequence: 0.1023, 0.2024, 0.3025, 0.7024, 0.9323, 0.12023, 0.78923, 0.6723, 0.12323, 0.9033, 0.34523, 0.123423
好像您在主程序上使用了时钟,这意味着它确实如您所说计算了函数的总运行时间。 为了计算您完成一个序列所花费的时间,您应该考虑移动
clock_gettime(CLOCK_REALTIME, &start);
并且:
clock_gettime(CLOCK_REALTIME, &stop);
total_time = (stop.tv_sec - start.tv_sec) * 1e9;
total_time = (total_time + (stop.tv_nsec - start.tv_nsec)) * 1e-9;
对于 printFibonacci 的开始和结束,恭敬地,在这种情况下,在每次递归中,您将看到序列发生的确切时间。
按照问题中的编码,计算整个序列的时间,包括用户输入数字所花费的时间和 printf
输出值所花费的时间。这是没有意义的。
此外,您将秒数乘以 109,然后将纳秒数也除以 109:您应该做一个或另一个,但不能同时做。
如果你想为每个数字的计算计时,你应该在前 2 个数字相加之前检索时钟,并在 3 个赋值之后立即重新检索时钟。尝试对这样一个简单的操作计时是相当困难的:clock_gettime()
不是正确的工具,您更有可能只测量 clock_gettime
的开销,CLOCK_REALTIME
的不精确性,可能当您测量 CLOCK_REALTIME
而不是当前进程的运行时时,异步进程会中断您的程序。您可能应该改用 clock()
,但测量值可能微不足道。
中间时间应存储在 static
数组中,以便 main
打印它们。
这是修改后的版本:
#include <stdio.h>
#include <time.h>
#define MAX_TIMINGS 100
static double timings[MAX_TIMINGS];
static int timing_index = 2;
void printFibonacci(int n) {
static int n1 = 0, n2 = 1, n3;
if (n > 0) {
struct timespec start, stop;
clock_gettime(CLOCK_REALTIME, &start);
n3 = n1 + n2;
n1 = n2;
n2 = n3;
clock_gettime(CLOCK_REALTIME, &stop);
if (timing_index < MAX_TIMINGS) {
timings[n] = (stop.tv_sec - start.tv_sec) * 1e9 +
(stop.tv_nsec - start.tv_nsec);
}
printf("%d ", n3);
printFibonacci(n - 1);
}
}
int main() {
int i, n;
double total_time = 0;
printf("Enter the number of elements: ");
scanf("%d", &n);
printf("Fibonacci Series: ");
printf("%d %d ", 0, 1);
printFibonacci(n - 2);
printf("\n");
printf("Time taken for each number:");
for (i = 0; i <= n; i++) {
printf(" %.0fns", timings[i]);
total_time += timings[i];
}
printf("\n");
printf("Total time: %.0fns\n", total_time);
return 0;
}
输出:
Enter the number of elements: 20
Fibonacci Series: 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
Time taken for each number: 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns
Total time: 0ns
毫不奇怪,所有时间都是空的。测量顺序生成器的每个数字的时间是没有意义的。
相反,时间对于经典的递归实现很重要,其中涉及许多递归调用,即使是中等大的参数。
这里有一个比较经典的例子:
#include <stdio.h>
#include <time.h>
unsigned long long fib(int n) {
if (n < 2)
return n;
else
return fib(n - 1) + fib(n - 2);
}
int main() {
int i, n;
double total_time = 0;
printf("Enter the number of elements: ");
if (scanf("%d", &n) != 1)
return 1;
double timings[n + 1];
printf("Fibonacci Series:");
for (i = 0; i <= n; i++) {
struct timespec start, stop;
unsigned long long res;
clock_gettime(CLOCK_REALTIME, &start);
res = fib(i);
clock_gettime(CLOCK_REALTIME, &stop);
timings[i] = ((stop.tv_sec - start.tv_sec) * 1e9 +
(stop.tv_nsec - start.tv_nsec));
printf(" %llu", res);
}
printf("\n");
printf("Time taken for each number:");
for (i = 0; i <= n; i++) {
printf(" %.0fns", timings[i]);
total_time += timings[i];
}
printf("\n");
printf("Total time: %.0fns\n", total_time);
return 0;
}
输出:
Enter the number of elements: 20
Fibonacci Series: 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
Time taken for each number: 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 0ns 1000ns 0ns 1000ns 1000ns 2000ns 5000ns 6000ns 10000ns 18000ns 38000ns 69000ns
Total time: 151000ns