基准测试(for循环的执行时间):随着for循环极限的增加,我们不应该有一个单调递增的函数吗?
Benchmarking (execution time of a for loop): shouldn't we have an monotonic increasing function with the increase of the limit of the for loop
我想对 for 循环进行基准测试。我决定将 for 循环中的变量增加 100 并相应地测量时间。
#include <cstdio>
#include <ctime>
#include <time.h>
#include <iostream>
#include <random>
#include <iomanip> // std::setprecision
using namespace std;
double difference(timespec start, timespec end);
int main()
{
timespec time1, time2;
for(int limit = 0; x < 100000; limit+= 100)
{
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
int temp = 0;
for (int i = 0; i< limit; i++)
temp+=temp;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
std::cout << std::fixed;
std::cout << std::setprecision(5);
cout<<x <<" " << difference(time1,time2)<<endl;
}
return 0;
}
double difference(timespec start, timespec end)
{
timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return (temp.tv_sec + temp.tv_nsec) / 1000000000.00;
}
图表
y 轴表示以秒为单位的时间,x 轴表示迭代的增加限制。
Hypothesis: With the increasing limit the time should increase. We
should have a Strictly Increasing Function
曲线显示为其他。为什么循环 5300
次需要 0.00001
秒,循环 5400
次需要 0.00002
秒。正如您在图表中看到的那样,我们有很多次遇到这种情况。
您可以清楚地看到曲线中的台阶,这意味着您在测量中遇到了精度障碍。换句话说,clock_gettime
调用无法为您提供任何更准确的值,并且多次迭代测量的是相同的时间值,因为运行之间没有足够大的差异。
小峰和小谷可以用舍入误差来解释。有一次你在时钟 'tick' 之前调用了 clock_gettime
,而下一次是在 'tick' 之后调用了它。这可能会导致第一次看起来短一个'tick'。这里的'tick'是时钟的精度。
Hypothesis:
假设是对现象的解释。由于您是在实际观察任何现象之前提出这一点,因此它不能成为假设。此外,如果如您所说,它直接与观察结果相矛盾,则不能作为对它们的解释,因此不是假设。
With the increasing limit the time should increase. We should have a Strictly Increasing Function
据我所知,观察结果与此并不矛盾。
曲线中的伪影很容易用时钟的有限分辨率来解释:它显然无法测量小于 1e-5 的时间差;小于 1e-5 的变化将显示为扁平线或离散的 1e-5 变化。
我想对 for 循环进行基准测试。我决定将 for 循环中的变量增加 100 并相应地测量时间。
#include <cstdio>
#include <ctime>
#include <time.h>
#include <iostream>
#include <random>
#include <iomanip> // std::setprecision
using namespace std;
double difference(timespec start, timespec end);
int main()
{
timespec time1, time2;
for(int limit = 0; x < 100000; limit+= 100)
{
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
int temp = 0;
for (int i = 0; i< limit; i++)
temp+=temp;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
std::cout << std::fixed;
std::cout << std::setprecision(5);
cout<<x <<" " << difference(time1,time2)<<endl;
}
return 0;
}
double difference(timespec start, timespec end)
{
timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return (temp.tv_sec + temp.tv_nsec) / 1000000000.00;
}
图表
y 轴表示以秒为单位的时间,x 轴表示迭代的增加限制。
Hypothesis: With the increasing limit the time should increase. We should have a Strictly Increasing Function
曲线显示为其他。为什么循环 5300
次需要 0.00001
秒,循环 5400
次需要 0.00002
秒。正如您在图表中看到的那样,我们有很多次遇到这种情况。
您可以清楚地看到曲线中的台阶,这意味着您在测量中遇到了精度障碍。换句话说,clock_gettime
调用无法为您提供任何更准确的值,并且多次迭代测量的是相同的时间值,因为运行之间没有足够大的差异。
小峰和小谷可以用舍入误差来解释。有一次你在时钟 'tick' 之前调用了 clock_gettime
,而下一次是在 'tick' 之后调用了它。这可能会导致第一次看起来短一个'tick'。这里的'tick'是时钟的精度。
Hypothesis:
假设是对现象的解释。由于您是在实际观察任何现象之前提出这一点,因此它不能成为假设。此外,如果如您所说,它直接与观察结果相矛盾,则不能作为对它们的解释,因此不是假设。
With the increasing limit the time should increase. We should have a Strictly Increasing Function
据我所知,观察结果与此并不矛盾。
曲线中的伪影很容易用时钟的有限分辨率来解释:它显然无法测量小于 1e-5 的时间差;小于 1e-5 的变化将显示为扁平线或离散的 1e-5 变化。