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






2.77/5 (14投票s)
本文是系列文章的第一篇,对 Java 和 C# .NET 的语言性能进行了客观的分析。
- 下载 mathperformance_data_summary - 13.6 KB
- 下载 mathperformance_src_c_dotnet - 24.66 KB
- 下载 mathperformance_src_java - 16.27 KB
引言
本系列文章对 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); |
结果分析
所有时间单位均为毫秒,是 5 次测试运行的平均值。
值越低越好。
在这些图中显示了函数的相对性能,与人们普遍认为的可能相反的是,除了幂运算和乘法之外,Java 实际上似乎优于 C# .Net 语言。然而,值得注意的是,Java 的加法和减法情况实际上低于 0,这表明对照组运行得特别慢,或者可能发生了一些优化。由于 Java 的对照组显示出良好的一致性,因此前者不太可能。
值越低越好。
在此图中,显示了 5 次运行中完成对照组的总时间。有趣的是,.Net 语言由于从第 1 次运行到后续运行的总体时间持续减少,表明发生了一些优化;在 Java 中看不到这种效果,Java 的性能似乎持续更好(也许是因为对照组本身基于加法函数,而根据以上结果,该函数表现明显更好)。
摘要
- 对照组,即循环和加法函数,在 Java 中表现更稳定。
- .Net 对重复函数进行了一些优化,而 Java 没有。
- Java 在除法、加法和减法函数方面表现更好(尽管需要进一步测试来确认)。
- .Net 在乘法和幂函数方面表现更好。
其他参考文献
请稍后回来查看关于磁盘访问和接口更新性能比较的其他文章。
历史
版本 1.0.0.1 - 测试 +, -, *, /, 和幂运算。