Did I just prove that sieve of Eratosthenes is less efficient than trial division?
我试图比较两种算法的运行速度:一个用于打印质数(10,000个数字)的蛮力C程序和一个Eratosthenes C程序筛网(也包含10,000个质数)。
我为筛分算法测得的运行时间为:0.744秒
我为蛮力算法测得的运行时间为:0.262秒
但是,有人告诉我,Eratosthenes算法的Sieve比蛮力方法更有效,因此我认为它的运行速度会更快。 所以我错了或者我的程序有缺陷(我对此表示怀疑)。
因此,我的问题是:由于得到的结果与预期相反,这是否证明了Eratosthenes的Sieve在速度方面的确比试验部门效率更低?
我不确定是否相关,但是我使用的是Dev C ++编译器和Windows 7。
TL; DR:仅在一种输入大小下比较代码变体的速度是没有意义的;比较经验的增长顺序确实反映了代码的算法性质,并且对于相同的输入大小测试范围,将在不同的测试平台上保持一致。比较绝对速度值仅对表现出相同渐近或至少局部增长行为的代码变体有意义。
仅以一个输入大小来衡量两个实现的速度是不够的。通常需要几个数据点来评估我们的代码在运行时的经验增长顺序(因为代码可以在不同的输入大小下运行)。它是基于输入大小比率的运行时间比率的对数。
因此,即使某些输入
因此,算法效率的真正衡量标准是运行时间复杂度(以及其空间复杂度,即内存需求)。当我们凭经验测量它时,我们仅测量是否针对手头的特定代码(在特定的输入大小范围内)而不是算法本身,即它的理想实现。
特别是,在产生的n个素数中,试验划分的理论复杂度为
所以不,这没有证明。一个数据点是没有意义的,至少需要三个数据点才能获得"全局",即能够确定地预测较大输入大小所需的运行时间空间。
科学方法的目的在于确定性地进行预测。
顺便说一句,您的运行时间很长。 10,000个素数的计算应该几乎是瞬时的,对于在快速框上运行的C程序而言,它的秒数要不到1/100秒。也许您也在测量打印时间。别。 :)
不,经过的运行时间并不是衡量效率的标准,因为运行时间因平台而异-说"我的算法在10秒钟内运行"几乎没有提供关于算法本身的信息。除此之外,您还需要列出整个环境规范和同时运行的其他进程,这会造成很大的麻烦。因此,订单符号(大哦,小哦,欧米茄等)的发展。
效率通常分为两个部分:
...其中一种算法可能具有极高的时间效率,但在空间方面却效率极低。反之亦然。当缩放需要为给定输入
注意,我附加了Big Oh符号的链接-姐妹符号都可以在该Wikipedia页面上找到,通常是一个不错的起点。它还将涉及时空效率的差异。
使用Big Oh的时间效率小应用程序:
考虑一下Racket中的以下递归函数(如果我知道的话,将在Python中使用-我可以做的最好的伪代码):
1 2 3 4 5 6 | (define (fn_a input_a) (cond [(empty? input_a) empty] [(empty? (rest input_a)) input_a] [(> (first input_a) (fn_a (rest input_a))) (cons (first input_a) empty)] [else (fn_a (rest input_a))])) |
...我们看到:
还需要注意的是,根据Big Oh的正式定义,声明
注意,请阅读正式定义!
Does a longer run-time mean a less efficient algorithm?
不必要。程序的效率不仅通过其花费的时间来衡量,而且还通过它所占用的资源来衡量。在考虑效率时,空间是另一个要牢记的因素。
从维基:
For maximum efficiency we wish to minimize resource usage. However,
the various resources (e.g. time, space) can not be compared directly,
so which of two algorithms is considered to be more efficient often
depends on which measure of efficiency is being considered as the most
important, e.g. is the requirement for high speed, or for minimum
memory usage, or for some other measure?
通常通过算法处理大型输入的效率来衡量算法的效率。 10,000个数字不是很大的输入,因此您可能需要使用更大的数字才能使Eratosthenes的筛子开始变得更快。
另外,您的一种实现可能很大
最后,可以通过所需的内存量来衡量算法的效率(但是这种方法并不常见,特别是因为当今的内存是如此便宜)
简而言之,是的,如果您通过效率来表示节省时间。也有内存注意事项。
不过要小心如何测量-确保计时工具准确无误。
确保没有其他任何运行时在同一台计算机上进行测量。
确保测量几次,并取平均值和平均值进行比较。
考虑让某人查看您的代码以检查它是否在执行您认为正在执行的操作。
总的来说:是的,但是当您处于1秒以下的范围内时,会产生很多噪音,这可能会令人困惑...
多次运行每个测试,并对结果使用一些统计信息(例如,平均值或均值/偏差取决于您的关注程度)
和/或使其做更多的工作-例如查找更多的质数