C#与C及C++的性能有哪些差异?
C#与C及C++的性能有哪些差异?
C# 与 C 、 C++ 、 D 、 Java 的性能比较(二)
(文章专自http://mag.vchelp.net) jason
Picalcr. 递归。通过 listing5 所示的算法计算圆周率。对每种语言,我们会做 10000 次运算,考虑到 java 堆栈在深层地归时很容易被耗尽,所以每次运算限制在 4500 次递归以内。
Sieve. 叠代。通过 Listing 6 所示的迭代算法( Eratosthenes's sieve ( http://www.math.utah.edu/~alfeld/Eratorthenes.html ))得到质数。每种语言的实现其迭代次数是 10,000,000 。
Strcat. 字符串连接 --- 通常是大量运行时开销的根源,也是导致程序低效的潜在领域。(我以前做过一个对性能敏感的项目,通过改善效率底下的字符串连接,我获得了 10% 的整体性能提升) . 测试通过构造四种不同类型的变量 :short,int, double 和一个 string ,然后把它们连接成一个 string 变量完成,连接时添加用分号分割.在连接的时候采用四种不同的连接方
法 :1) 默认连接方法 2) 故意构造出来的导致效率低下的连接方法 3)C 语言种典型的 printf/Format 格式,需要重新分配空间 4) 为提高性能而进行的硬编码 . 代码摘录见 Listing7
Strswtch. 通过级联 switch 进行字符串比较 . 通过语言支持的 switch 语句进行比较或者通过一些列的 if-else 语句模拟( Listing 8 ).这项测试是为了检验 c# 的字符串处理功能是否如他所声称的那样高效.测试分成两部分 : 首先是进行字符串之间的赋值,也就是同一身份的比较(译者注:也就是字符串内部的指针直接复制,不涉及到字符串内容的拷贝).其次是通过字符串的拷贝后进行比较,这样就避免了同一身份比较而是进行进行字符串之间的字面比较.每种语言上都进行 850000 次叠代,因为超过这个次数后会导致 java vm 内存耗尽.
strtok 字符串分段。字符串的运行效率也极低,有时甚至引发严重的运行开销。这个测试( Listing 9)读取一个文本文件的全部内容至一个字符串,然后拆分成段。第一个变量用字符分隔符:‘;'分隔字符串,并忽略所有的空白。第二个变量也用分号分隔,但保留了空白。第三个和第四个变量用字符串分隔符:<->,并相应的忽略和保留了空白处。C里仅第二个变量用了strtok(),C++四个变量都用STLSoft的string_tokeniser模板,但各自正确给参数赋值。C#第一个变量用System.String.Split(),2至4变量用SynSoft.Text.Tokeniser.Tokenise();Java用java.util.StringTokenizer,仅支持变量2和4(注:我选用STLSoft的string_tokeniser模板不是我要为STLSoft作宣传,而是测试表明它比Boost的快2.5倍,而Boost是大多数开发人员在查找库时的首选)。
结果
在 noop测试中,表2列出了以微秒(us)为单位装载一个空操作的平均开销。显然C,C++,D的差别不合逻辑,每一个大约是5-6毫秒,而Intel确低至2ms。我所想到的唯一可能是这个编译器优化了所有的C实时运行库的初始化工作。如果是这样,这个性能在其他非试验性即实际应用中不能体现出来,因为它至少需要一些C … ,这有待深入研究。
C#用了大约70ms,Java约0.2秒。C#和Java的装载清晰的表明其实时开销在于它们的实时运行的结构基础(VM和支持DLLs)。但是除了大规模的命令行的商业化批处理,对极大型系统(上百万条代码)或CGI的基础构建,启动开销在大多数情况下不重要。重荷服务器允许在数秒内启动,所以语言间200ms的差异就微乎其微了。
其余的结果分三部分显示。图 2和3分别展示了字符串连接和分段的结果。图1包含了其余全部的测试结果,我们现在先来看看它。
图 1中,对各测试项,C,C++,D,Java的结果均以其相应测试项C#运行时间的百分比显示。因此,在100%线上下波动的结果说明与C#性能相当。高百分比说明C#性能较优,而低百分比表明C#性能相对较差。