其他人已经提供了一些优秀的commen包括对生成的汇编代码的分析。我强烈建议你仔细阅读。正如他们指出的,这种问题如果没有量化就不能真正回答,所以让我们一起玩吧。
首先,我们将需要一个程序。我们的计划是这样的:我们将生成长度为2的字符串,并依次尝试所有函数。我们运行一次来初始化缓存,然后分别使用我们可用的最高分辨率进行4096次迭代。一旦完成,我们将计算一些基本的统计数据:min,max和简单移动平均值并转储它。然后我们可以做一些基本的分析。
除了你已经显示的两种算法之外,我将展示第三个选项,它根本不涉及使用计数器,而是依赖于减法,我将通过投掷来混合东西在std::strlen
,只是为了看看会发生什么。这将是一个有趣的回合。
通过我们的小程序已经写入电视的魔力,所以我们用gcc -std=c++11 -O3 speed.c
编译它,我们得到起动产生一些数据。我做了两个单独的图,一个是字符串,大小从32到8192字节,另一个是字符串,长度从16384到1048576字节。在下面的图表中,Y轴是在纳秒内消耗的时间,X轴以字节为单位显示字符串的长度。
事不宜迟,让我们来看看从32 “小” 的字符串表现为8192个字节:
现在这是有趣的。 std::strlen
的功能不仅仅是性能优于所有的功能,而且它的性能也更加稳定。
会,形势的变化,从16384如果我们看一下大串一路1048576个字节长?
的排序。差异变得更加明显。由于我们的自定义编写的功能唾手可得,std::strlen
继续执行令人钦佩。
一个有趣的现象,使的是,你不一定能转化的C++的指令数(甚至,汇编指令数)的性能,因为其功能包括机构较少的指令有时需要更长的时间来执行。
更有意思的是 - 和重要观察是要注意str::strlen
功能如何执行。
那么,这一切是什么让我们?
第一个结论:不要重新发明轮子。使用可用的标准功能。它们不仅是已经写好的,而且它们的优化程度非常高,几乎肯定会胜过你可以编写的任何东西,除非你是Agner Fog。第二个结论:除非你有一个硬数据从一个代码或函数的特定部分是你的应用程序中的热点,不要打扰优化代码。程序员通过查看高级功能在检测热点方面非常不好。
第三个结论:宁可为了提高代码的性能算法最优化。让你的思想工作,并让编译器随机播放。
您原来的问题是:“为什么函数slen2
慢于slen1
?”我可以说,没有更多的信息就不容易回答,即使如此,它可能会比你所关心的要长得多,涉及更多。相反,我会说这是:
谁在乎,为什么?你为什么还要打扰呢?使用std::strlen
- 这比任何你可以设置的更好 - 然后继续解决更重要的问题 - 因为我确信这个不是是你应用程序中最大的问题。
为什么使用double而不是unsigned long?另外,您应该尝试编译而不进行优化并查看结果。哦,你应该运行约二十次,并计算平均持续时间。 – 2011-05-30 20:01:09
分支预测失败?不必要的数据副本?尝试查看生成的程序集。此外,尝试开启优化,它可能会解决问题。 – dmckee 2011-05-30 20:02:25
你使用什么样的编译器?我用gcc 4.4.5运行它,它们几乎在同一时间,大约2s。随着我设置为110021100,他们都使用大约19秒。 – 2011-05-30 20:03:10