.NET で float のパフォーマンスをテストしているときに、奇妙なケースに出くわしました。特定の値では、乗算が通常よりもかなり遅くなるようです。テストケースは次のとおりです。
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、デバッガーが接続されていません。