为什么在使用通用包装器 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_mathProviderstopwatch_native 换了。实际结果是相反的:如您所料,数学提供程序较慢。