Performance 我可以使用大O表示法来比较同一算法的优化和非优化实现的性能吗?
我在写一篇关于一个O(n)复杂度算法的优化文章。它仍然有O(n)复杂度,但执行时间大大提高。我说我改进了O部分对吗?如果没有,我怎么能提到算法的速度呢?如果您只改进了常数,那么需要提供具体的计时统计数据。Big-O表示法仅适用于渐近行为。例如,您需要指定一组给定的测试数据,并显示您的优化版本比未优化版本快X%或X倍Performance 我可以使用大O表示法来比较同一算法的优化和非优化实现的性能吗?,performance,sorting,big-o,complexity-theory,Performance,Sorting,Big O,Complexity Theory,我在写一篇关于一个O(n)复杂度算法的优化文章。它仍然有O(n)复杂度,但执行时间大大提高。我说我改进了O部分对吗?如果没有,我怎么能提到算法的速度呢?如果您只改进了常数,那么需要提供具体的计时统计数据。Big-O表示法仅适用于渐近行为。例如,您需要指定一组给定的测试数据,并显示您的优化版本比未优化版本快X%或X倍 您没有改进实现的渐进行为,因为原始版本和优化版本都在O(n)时间内运行。算法的复杂性将保持不变,但您将运行时间减少了x倍。例如,一个9001n^2算法和一个n^2算法都是大O(n^2
您没有改进实现的渐进行为,因为原始版本和优化版本都在O(n)时间内运行。算法的复杂性将保持不变,但您将运行时间减少了x倍。例如,一个9001n^2算法和一个n^2算法都是大O(n^2),但是一个要快9001倍。因此,从第一个到第二个,运行时间减少了9001倍。O(n)=O(n),所以不,你不能说任何关于大O复杂性的改变,因为大O复杂性没有改变 您可以简单地说,运行时间提高了X倍或某个百分比,或者您可以使用。是改变渐进复杂性的优化的一个很好的例子 这与排序无关,但它确实解决了您提出的整个问题,因此我将在这里重现答案,以给出一个例子,其中优化可以在Big-O表示法中看到:
TL;DR:运行时需要测量,而不是“计算”
运行时高度依赖于编译器。我在三级非常受欢迎的C++编译器上进行了优化2级的测试,没有进行整个程序优化。一个给出三次运行时间,两个给出线性运行时间。根据使用的是amd64还是x86编译器,Microsoft同时拥有最佳和最差的位置 我使用I=1、10、100、200、1000、2000、10000、20000以及至少需要两秒钟的迭代来运行。时间是根据我的性能计数器的频率报告的,不是以秒为单位,但时基是稳定的,所以它和其他任何计数器一样好。这是一个核心i5 Haswell,如果有人关心的话 使用Visual Studio 2013更新3,x86编译
timing unit is 2240908.000000 per second
i iterations elapsed time
1 1000000000 7974255
10 100000000 40455055
100 100000 30560052
200 10000 24365172
1000 100 30615626
2000 10 24530866
timing unit is 2240908.000000 per second
i iterations elapsed time
1 1000000000 6123844
10 1000000000 29860683
100 100000000 25790181
200 10000000 4977144
1000 10000000 23488811
2000 1000000 4750398
10000 1000000 23544227
20000 100000 4726392
timing unit is 2240908.000000 per second
i iterations elapsed time
1 1000000000 6460830
10 1000000000 25768266
100 100000000 30732123
200 10000000 6294949
1000 10000000 31590581
2000 1000000 6206729
10000 1000000 31528696
20000 100000 6217971
使用Visual Studio 2013更新3,x64编译
timing unit is 2240908.000000 per second
i iterations elapsed time
1 1000000000 7974255
10 100000000 40455055
100 100000 30560052
200 10000 24365172
1000 100 30615626
2000 10 24530866
timing unit is 2240908.000000 per second
i iterations elapsed time
1 1000000000 6123844
10 1000000000 29860683
100 100000000 25790181
200 10000000 4977144
1000 10000000 23488811
2000 1000000 4750398
10000 1000000 23544227
20000 100000 4726392
timing unit is 2240908.000000 per second
i iterations elapsed time
1 1000000000 6460830
10 1000000000 25768266
100 100000000 30732123
200 10000000 6294949
1000 10000000 31590581
2000 1000000 6206729
10000 1000000 31528696
20000 100000 6217971
使用cygwin g++4.8.2,64位编译
timing unit is 2240908.000000 per second
i iterations elapsed time
1 1000000000 7974255
10 100000000 40455055
100 100000 30560052
200 10000 24365172
1000 100 30615626
2000 10 24530866
timing unit is 2240908.000000 per second
i iterations elapsed time
1 1000000000 6123844
10 1000000000 29860683
100 100000000 25790181
200 10000000 4977144
1000 10000000 23488811
2000 1000000 4750398
10000 1000000 23544227
20000 100000 4726392
timing unit is 2240908.000000 per second
i iterations elapsed time
1 1000000000 6460830
10 1000000000 25768266
100 100000000 30732123
200 10000000 6294949
1000 10000000 31590581
2000 1000000 6206729
10000 1000000 31528696
20000 100000 6217971
以下是基准测试驱动程序:
#include <windows.h>
#include <stdio.h>
extern long long the_function(int i);
int main(int argc, char** argv)
{
LARGE_INTEGER timing_freq;
QueryPerformanceFrequency(&timing_freq);
printf("timing unit is %f per second\n", (double)timing_freq.QuadPart);
for( int a = 1; a < argc; ++a ) {
char* pEnd;
int i = strtoul(argv[a], &pEnd, 0);
if (*pEnd) {
printf("Couldn't understand \'%s\'\n", argv[a]);
return 1;
}
LARGE_INTEGER before;
LARGE_INTEGER after;
long long iterations = 1;
do {
iterations *= 10;
QueryPerformanceCounter(&before);
for( int k = 0; k < iterations; ++k )
the_function(i);
QueryPerformanceCounter(&after);
} while (after.QuadPart - before.QuadPart < 2 * timing_freq.QuadPart);
printf("%d\t%lld\t%lld\n", i, iterations, after.QuadPart - before.QuadPart);
}
return 0;
}
#包括
#包括
函数(inti)的外部长;
int main(int argc,字符**argv)
{
大整数定时频率;
查询性能频率(和定时频率);
printf(“定时单位为每秒%f\n”,(双)定时频率四部分);
对于(int a=1;a
以及正在评估的代码:
long long the_function(int i)
{
long long x = 0;
for(int n = 0; n < i; n++)
for (int j = 0; j < n*n; j++)
x++;
return x;
}
long_函数(int i)
{
长x=0;
对于(int n=0;n
“我怎么才能知道算法的速度?”——你刚才就是这么做的,不是吗/大O不是指这个常数吗?还有另一个变量可以吗?大O表示渐近符号,这在这里基本上意味着“当它接近无穷大时”。当n接近无穷大时,9001n^2和n^2之间的差值变得很小,因此它们在大O符号中被视为相同的,因为在这个尺度下,常数并不重要。我认为没有一个形式化的术语与大O相一致,它包括常量,主要是因为大O被用来表示算法在所有数据集的大小上都是有效的。