我想检查对n个元素数组的迭代是否具有复杂度O(n)?为了对抗编译器优化,我将数组初始化为{-1,1,-1,1 ...},然后计算所有元素的总和。这是代码:
#include <iostream>
#include <chrono>
#include <string>
#include <vector>
using namespace std;
const int numIter = 1000;
chrono::system_clock::time_point getTime()
{
return std::chrono::high_resolution_clock::now();
}
void showDeltaT( const string& text, const std::chrono::system_clock::time_point& t1, std::chrono::system_clock::time_point& t2 )
{
cout <<
text <<
std::chrono::duration_cast<std::chrono::milliseconds>( t2 - t1 ).count() <<
" milliseconds" <<
"\n"
;
}
void test( int size )
{
cout << "test for size " << size << "\n";
std::vector<int> array( size );
for ( int i = 0; i < size; i++ )
{
array[i] = i % 2 ? 1 : -1;
}
auto t1 = getTime();
int s = 0;
for ( int i = 0; i < numIter; i++ )
{
for ( int k = 0; k < size; k++ )
{
s += array[k];
}
}
auto t2 = getTime();
showDeltaT( "the sum is: " + to_string( s ) + " and the time is ", t1, t2 );
cout << endl;
}
void main()
{
test( ( int )1.e6 );
test( ( int )2.e6 );
test( ( int )3.e6 );
test( ( int )4.e6 );
test( ( int )5.e6 );
test( ( int )6.e6 );
test( ( int )7.e6 );
test( ( int )8.e6 );
test( ( int )9.e6 );
test( ( int )10.e6 );
getchar();
}
令人惊讶的是,我没有得到理想的结果。似乎时间非线性增加:
测试尺寸1000000 总和为:0,时间为121毫秒
测试尺寸2000000 总和为:0,时间为316毫秒
测试尺寸3000000 总和为:0,时间为580毫秒
测试尺寸4000000 总和为:0,时间为828毫秒
测试尺寸5000000 总和为:0,时间为1063毫秒
测试尺寸6000000 总和是:0,时间是1285毫秒
测试尺寸7000000 总和为:0,时间为1521毫秒
测试尺寸8000000 总和为:0,时间为1756毫秒
测试尺寸9000000 总和为:0,时间为1998毫秒
测试尺寸10000000 总和为:0,时间为2260毫秒
你能解释一下这种行为吗?
更新: 正如评论中提到的,依赖性实际上是线性的。是的,它是真实的:
现在出现了新的问题:为什么它的延长没有通过(0,0)?
答案 0 :(得分:0)
我的猜测是时间分辨率(毫秒)要小到精确。任何来自外部的“污染”(操作系统执行其他一些任务)都会破坏结果...尝试更苛刻的事情,请为相同的测试获得超过一次运行的执行时间(对于100k元素,请等三次)做一个意思)。如果您真的想测量性能,请看一下这个例子:
http://web.cse.ohio-state.edu/~teodores/download/teaching/cse675.au08/CSE675.02.Performance.pdf