为什么在使用通用包装器 class 时添加 1,000,000 个浮点数会更快?
Why is addition of 1,000,000 floats faster when using a generic wrapper class?
我有一个简单的 class,它提供独立于数字类型的数学运算。为了简化我的问题,我将 classes 减少为以下内容:
public abstract class MathProvider<T>
{
public abstract T Add(T a, T b);
}
public class FloatMathProvider : MathProvider<float>
{
public override float Add(float a, float b)
{
return a + b;
}
}
我假设我的包装器 class 的数学运算比通常简单地添加两个浮点数要慢。我看到了相反的结果。
当我 运行 下面的程序,并使用 StopWatch
class 测量性能时,似乎使用包装器 class.[=16 时添加 1,000,000 个浮点数实际上更快=]
public class Program
{
static void Main(string[] args)
{
var mathProvider = new FloatMathProvider();
var points = 1000000;
var dataOne = GenerateRandomFloats(points);
var dataTwo = GenerateRandomFloats(points);
var stopwatch_mathProvider = new Stopwatch();
var stopwatch_native = new Stopwatch();
stopwatch_mathProvider.Start();
for (int i = 0; i < points; i++)
{
var test = dataOne[i] + dataTwo[i];
}
stopwatch_mathProvider.Stop();
stopwatch_native.Start();
for (int i = 0; i < points; i++)
{
var test = mathProvider.Add(dataOne[i], dataTwo[i]);
}
stopwatch_native.Stop();
Console.WriteLine("float:\t\t" + stopwatch_native.ElapsedTicks);
Console.WriteLine("Provider:\t" + stopwatch_mathProvider.ElapsedTicks);
Console.Read();
}
static float[] GenerateRandomFloats(long points)
{
var data = new float[points];
var random = new Random();
for (int i = 0; i < points; i++)
{
data[i] = 100f * (float)random.NextDouble();
}
return data;
}
}
以下是发布模式下的输出示例:
float: 10182
Provider: 1560
在调试模式下:
float: 38717
Provider: 13127
这似乎有违直觉。有人可以解释为什么通过通用包装器 class 添加速度更快吗?此外,当包裹在通用 class?
中时,还有哪些其他操作通常更快?
喝点咖啡,你在测试中把 stopwatch_mathProvider
和 stopwatch_native
换了。实际结果是相反的:如您所料,数学提供程序较慢。
我有一个简单的 class,它提供独立于数字类型的数学运算。为了简化我的问题,我将 classes 减少为以下内容:
public abstract class MathProvider<T>
{
public abstract T Add(T a, T b);
}
public class FloatMathProvider : MathProvider<float>
{
public override float Add(float a, float b)
{
return a + b;
}
}
我假设我的包装器 class 的数学运算比通常简单地添加两个浮点数要慢。我看到了相反的结果。
当我 运行 下面的程序,并使用 StopWatch
class 测量性能时,似乎使用包装器 class.[=16 时添加 1,000,000 个浮点数实际上更快=]
public class Program
{
static void Main(string[] args)
{
var mathProvider = new FloatMathProvider();
var points = 1000000;
var dataOne = GenerateRandomFloats(points);
var dataTwo = GenerateRandomFloats(points);
var stopwatch_mathProvider = new Stopwatch();
var stopwatch_native = new Stopwatch();
stopwatch_mathProvider.Start();
for (int i = 0; i < points; i++)
{
var test = dataOne[i] + dataTwo[i];
}
stopwatch_mathProvider.Stop();
stopwatch_native.Start();
for (int i = 0; i < points; i++)
{
var test = mathProvider.Add(dataOne[i], dataTwo[i]);
}
stopwatch_native.Stop();
Console.WriteLine("float:\t\t" + stopwatch_native.ElapsedTicks);
Console.WriteLine("Provider:\t" + stopwatch_mathProvider.ElapsedTicks);
Console.Read();
}
static float[] GenerateRandomFloats(long points)
{
var data = new float[points];
var random = new Random();
for (int i = 0; i < points; i++)
{
data[i] = 100f * (float)random.NextDouble();
}
return data;
}
}
以下是发布模式下的输出示例:
float: 10182
Provider: 1560
在调试模式下:
float: 38717
Provider: 13127
这似乎有违直觉。有人可以解释为什么通过通用包装器 class 添加速度更快吗?此外,当包裹在通用 class?
中时,还有哪些其他操作通常更快?喝点咖啡,你在测试中把 stopwatch_mathProvider
和 stopwatch_native
换了。实际结果是相反的:如您所料,数学提供程序较慢。