65.9K
CodeProject 正在变化。 阅读更多。
Home

语言性能的客观分析 - 1)数学函数

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.77/5 (14投票s)

2008年4月26日

CPOL

4分钟阅读

viewsIcon

32083

downloadIcon

250

本文是系列文章的第一篇,对 Java 和 C# .NET 的语言性能进行了客观的分析。

mathperformance5.jpg

引言

本系列文章对 Java 和 C# .NET(2.0、3.0 和 3.5)的语言性能进行了客观的分析。这些文章的目的是结束关于 .Net 比 Java 好还是 Java 比 .Net 好的老生常谈的争论。本文分析了所有语言共有的标准基础数学运算符的性能,特别是构成大多数程序基本组件的数学运算符。

分析范围

在本文中,对以下函数进行了性能测试;

函数 Java 等效项 C# .Net 等效项
Add + +
Subtract - -
Multiply * *
Divide / /
Math.power(x, y) Math.Pow(x, y)

测试流程

要点

  • 测试通过控制台进行,所有情况在测试开始前系统负载最小。
  • 所有系统自动更新均已禁用。
  • 运行任务管理器,并设置为显示所有进程按 CPU 使用率降序排列;如果任何其他进程的使用率超过 5%,则重启测试。
  • 测试进程设置为单核亲和性(以减少 CPU 影响)。
  • 所有测试均执行 5 次,以减少数据噪音并提高准确性。
  • 所有测试均在同一多核系统上执行(减少其他进程的影响)。
  • 每个数学函数都测试 1000000000 次,以减少系统时间计算的误差并提高测量精度。
  • 通过对照组消除了循环 1000000000 次的影响。

测试系统

CPU Intel Core 2 Extreme QX6700 - Kentsfield, 2.66Ghz
主板 ASUSTeK - P5WDG2 WS Pro
内存 DDR2 - 5120MB, 双通道

测试代码

对照组

double y = 0;
int controlStart = System.Environment.TickCount;
for (int i = 0; i < 1000000000; i++)
{
   y = y + 1;
}
int controlEnd = System.Environment.TickCount;

Console.WriteLine(y.ToString());

对照组旨在消除测试函数循环的影响。为防止编译器优化移除循环,循环执行一个简单的加法函数,该函数用于所有函数测试(见下文)。此外,加法函数的值会在最后打印出来,同样是为了防止编译器优化因未使用而移除 y,然后移除循环本身。对照组重复执行 5 次,并使用所有(controlEnd - controlStart)的平均值作为 controlTime。y 在每次测试开始时重置为 0。

测试用例

y = 0;
double x = 0;
int addStart = System.Environment.TickCount;
for (int i = 0; i < 1000000000; i++)
{
   y = y + 1;
   x = x + 1;
}
int addEnd = System.Environment.TickCount;

Console.WriteLine(y.ToString());
Console.WriteLine(x.ToString());

测试用例尽可能地与对照组保持一致,只是增加了被测试的数学函数。在此示例中,正在测试加法函数,并且与对照组一样,x 的值会在最后打印出来,以防止因编译器优化而移除 x。此外,还可以通过比较结果的 x 值来确认各种被测试语言之间功能的等同性。测试时间计算为 ((addEnd - addStart) - controlTime)。

其他测试按如下方式执行;

函数 代码
Add x = x + 1;
Subtract x = x - 1;
Multiply x = x * 1.1;
Divide x = x / 1.1;
x = Math.Pow(x, 1.1);

结果分析

mathperformance4.jpg

所有时间单位均为毫秒,是 5 次测试运行的平均值。

mathperformance1.jpg

mathperformance2.jpg

值越低越好。

在这些图中显示了函数的相对性能,与人们普遍认为的可能相反的是,除了幂运算和乘法之外,Java 实际上似乎优于 C# .Net 语言。然而,值得注意的是,Java 的加法和减法情况实际上低于 0,这表明对照组运行得特别慢,或者可能发生了一些优化。由于 Java 的对照组显示出良好的一致性,因此前者不太可能。

mathperformance3.jpg

值越低越好。

在此图中,显示了 5 次运行中完成对照组的总时间。有趣的是,.Net 语言由于从第 1 次运行到后续运行的总体时间持续减少,表明发生了一些优化;在 Java 中看不到这种效果,Java 的性能似乎持续更好(也许是因为对照组本身基于加法函数,而根据以上结果,该函数表现明显更好)。

摘要

  • 对照组,即循环和加法函数,在 Java 中表现更稳定。
  • .Net 对重复函数进行了一些优化,而 Java 没有。
  • Java 在除法、加法和减法函数方面表现更好(尽管需要进一步测试来确认)。
  • .Net 在乘法和幂函数方面表现更好。

其他参考文献

请稍后回来查看关于磁盘访问和接口更新性能比较的其他文章。

历史

版本 1.0.0.1 - 测试 +, -, *, /, 和幂运算。

© . All rights reserved.