在 .NET 中测试浮点数的性能时,我偶然发现了一个奇怪的情况:对于某些值,乘法似乎比正常情况要慢得多。这是测试用例:
using System;
using System.Diagnostics;
namespace NumericPerfTestCSharp {
class Program {
static void Main() {
Benchmark(() => float32Multiply(0.1f), "\nfloat32Multiply(0.1f)");
Benchmark(() => float32Multiply(0.9f), "\nfloat32Multiply(0.9f)");
Benchmark(() => float32Multiply(0.99f), "\nfloat32Multiply(0.99f)");
Benchmark(() => float32Multiply(0.999f), "\nfloat32Multiply(0.999f)");
Benchmark(() => float32Multiply(1f), "\nfloat32Multiply(1f)");
}
static void float32Multiply(float param) {
float n = 1000f;
for (int i = 0; i < 1000000; ++i) {
n = n * param;
}
// Write result to prevent the compiler from optimizing the entire method away
Console.Write(n);
}
static void Benchmark(Action func, string message) {
// warm-up call
func();
var sw = Stopwatch.StartNew();
for (int i = 0; i < 5; ++i) {
func();
}
Console.WriteLine(message + " : {0} ms", sw.ElapsedMilliseconds);
}
}
}
结果:
float32Multiply(0.1f) : 7 ms
float32Multiply(0.9f) : 946 ms
float32Multiply(0.99f) : 8 ms
float32Multiply(0.999f) : 7 ms
float32Multiply(1f) : 7 ms
为什么 param = 0.9f 的结果如此不同?
测试参数:.NET 4.5,发布版本,代码优化开启,x86,没有附加调试器。