可能有重复:
C#中,double比float更快吗?
我编写了一个简单的基准测试来检查在我的应用程序中将double
数据类型更改为float
可以获得多少性能。这是我的代码:
// my form:
// one textbox: textbox1 (MultiLine property set to true)
// one button: button1 with event button1_Click
private void button1_Click(object sender, EventArgs e)
{
int num = 10000000;
float[] floats1 = new float[num];
float[] floats2 = new float[num];
float[] floatsr = new float[num]; // array for results
double[] doubles1 = new double[num];
double[] doubles2 = new double[num];
double[] doublesr = new double[num]; // array for results
Stopwatch stw = new Stopwatch();
log("Preparing data");
Random rnd = new Random();
stw.Start();
for (int i = 0; i < num; i++)
{
floats1[i] = NextFloat(rnd);
floats2[i] = NextFloat(rnd);
doubles1[i] = rnd.NextDouble();
doubles2[i] = rnd.NextDouble();
}
stw.Stop();
log(stw.Elapsed.TotalMilliseconds.ToString()+"ms");
stw.Reset();
log("");
stw.Start();
for (int i = 0; i <# i++)
{
floatsr[i] = floats1[i] * floats2[i];
}
stw.Stop();
log("Multiplying floats: " + stw.Elapsed.TotalMilliseconds.ToString() + "ms");
stw.Reset();
stw.Start();
for (int i = 0; i < num; i++)
{
doublesr[i] = doubles1[i] * doubles2[i];
}
stw.Stop();
log("Multiplying doubles: " + stw.Elapsed.TotalMilliseconds.ToString() + "ms");
stw.Reset();
stw.Start();
for (int i = 0; i < num; i++)
{
floatsr[i] = floats1[i] / floats2[i];
}
stw.Stop();
log("Dividing floats: " + stw.Elapsed.TotalMilliseconds.ToString() + "ms");
stw.Reset();
stw.Start();
for (int i = 0; i < num; i++)
{
doublesr[i] = doubles1[i] / doubles2[i];
}
stw.Stop();
log("Dividing doubles: " + stw.Elapsed.TotalMilliseconds.ToString() + "ms");
stw.Reset();
}
private void log(string text)
{
textBox1.Text = textBox1.Text + text + Environment.NewLine;
}
// I found that function somewhere on stackoverflow
static float NextFloat(Random random)
{
double mantissa = (random.NextDouble() * 2.0) - 1.0;
double exponent = Math.Pow(2.0, random.Next(-126, 128));
return (float)(mantissa * exponent);
}
我得到了如下结果(发布版本,无调试,英特尔移动酷睿双核T2500 2.0GHz 2MB的CPU):
Preparing data 5275,6862ms
Multiplying floats: 442,7865ms
Multiplying doubles: 169,4028ms
Dividing floats: 550,7052ms
Dividing doubles: 164,1607ms
我很惊讶,双精度浮点数的运算速度几乎比单精度浮点数的运算速度快3倍。我在这里搜索了“double float”,找到了这个链接:Is using double faster than float? 。
最佳回答侧重于CPU架构,但我不能同意这一点。
我怀疑其他原因导致了浮点数的低性能,因为我的CPU使用Intel SSE应该能够同时乘以或除以4个浮点数(打包的浮点指令)或2个双精度浮点数。所以浮点数应该更快。
也许编译器(或.NET中的CLR)以某种方式优化内存使用?
是否有任何方法可以优化并使浮点数更快?
请不要报告重复问题,我看到其他问题并不满足我。
根据Servy的建议,我更改了生成浮点数的方法后,我的结果现在看起来不错。
Preparing data 1367,0678ms
Multiplying floats: 109,8742ms
Multiplying doubles: 149,9555ms
Dividing floats: 167,0079ms
Dividing doubles: 168,6821ms
NextFloat
生成的数字分布与NextDouble
生成的数字分布非常不同。我不知道这是否有任何相关性。但请注意,NextDouble
生成介于0.0
和1.0
之间的数字,是1.0 / 2147483647.0
的整数倍。因此,数字的“结尾”并不真正随机,这在舍入计算的乘积或商时可能很重要。 - Jeppe Stig Nielsenfloat
或System.Single
情况),它可能需要先从数组中读取“扩展”数字,然后进行乘法运算,最后舍入并“缩小”数字以适应结果数组的32位“插槽”。而64位数字则不需要进行任何转换。 - Jeppe Stig Nielsen