C#:struct构造函数性能

Gre*_*rey 5 c# constructor struct

为什么使用构造函数创建结构比直接赋值更慢?在下面的代码中,我使用自定义构造函数获得10秒,而没有使用6秒!纯循环需要5秒钟.自定义构造函数比直接访问慢五倍(!sic).

是否有任何黑客或其他东西加速自定义构造函数?

class Program
{
    public struct Point
    {
        public int x, y;

        public Point(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }

    static void Main(string[] args)
    {
        Stopwatch sw = new Stopwatch();

        sw.Start();
        for(int i =0; i < int.MaxValue; i++)
        {
            var a = new Point(i, i);
        }
        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);

        sw.Restart();
        for (int i = 0; i < int.MaxValue; i++)
        {
            var a = new Point();
            a.x = i;
            a.y = i;
        }
        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);
        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 6

在下面的代码中,我使用自定义构造函数获得10秒

这不是需要10秒的代码,除非你有一台非常旧的机器.告诉我们你做错了什么,你正在运行未经优化的Debug构建或运行附带的调试器.不允许将内置于抖动中的优化器完成其工作的场景.

在代码周围循环运行10次,有助于摆脱启动开销和测量标准偏差,总是非常高速的代码就像这样.切换到发布版本并使用Ctrl + F5运行它.现在你得到了这段代码的实际性能,应该在1.5秒左右.这就是循环所花费的时间,优化器不会删除任何Point代码.它可以做什么,因为a变量没有在任何地方使用,构造函数没有可观察到的副作用.

让您想要完整删除的代码是典型的基准危险.您可以通过将a变量提升出循环并使用以下命令来防止这种情况发生:

  Console.WriteLine("{0}", sw.ElapsedMilliseconds, a);
Run Code Online (Sandbox Code Playgroud)

现在优化器不再能消除Point代码,因为变量在循环之外使用.如果它仍然同样快,你就会知道你正在对它进行基准测试.如何初始化结构并不重要.更多关于抖动优化器在这篇文章中的作用.


Mar*_*zek 5

您的分析代码简化了很多事情,但它也使得测量非常不准确.我建议使用像BenchmarkDotNet这样的工具来获得更准确的结果.

快速测试表明,直接分配速度要快一些,但没有像你声称的那样5倍:

[BenchmarkDotNet.Attributes.Benchmark(Baseline = true)]
public static Point GetPoint()
{
    return new Point(x, y);
}

[BenchmarkDotNet.Attributes.Benchmark]
public static Point GetPoint2()
{
    Point point = new Point();
    point.x = x;
    point.y = y;
    return point;
}
Run Code Online (Sandbox Code Playgroud)
    Method |       Mean |    StdDev | Scaled | Scaled-StdDev |
---------- |----------- |---------- |------- |-------------- |
  GetPoint | 10.2038 ns | 0.2593 ns |   1.00 |          0.00 |
 GetPoint2 |  9.3272 ns | 0.0767 ns |   0.91 |          0.02 |
Run Code Online (Sandbox Code Playgroud)

这是10%的差异,而不是5倍.