C #: struct constructor performance

Why is creating a structure with a constructor slower than a direct assignment? In the code below, I get 10 seconds with a custom constructor and 6 seconds without! A clean cycle takes 5 seconds. A custom constructor is five (! Sic) times slower than direct access.

Is there any hack or something to speed up the custom constructor?

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(); ax = i; ay = i; } sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); Console.ReadLine(); } } 
+5
source share
2 answers

In the code below, I get 10 seconds with a custom constructor

This is not a code that takes 10 seconds unless you have a very old machine. Tells us what you did wrong, you run an unoptimized Debug build or run an application with an attached debugger. The type of scenario in which the optimizer built into the jitter cannot do its job.

Put a loop around the code to run it 10 times, it helps to get rid of overhead and measure standard deviation, always very high on very fast code like this. Go to the Release build and run it with Ctrl + F5. Now you get a real performance of this code, which should be in the south of ~ 1.5 seconds. Here's how long the loops go, none of the point code is removed by the optimizer. This can be done because the variable a not used anywhere, and the constructor has no observable side effects.

Having code that you want to completely remove is a classic threat. This can be prevented by pulling the variable a from the loop and using:

  Console.WriteLine("{0}", sw.ElapsedMilliseconds, a); 

Now the optimizer can no longer eliminate the point code, since the variable is used outside the loop. You will find out that you are comparing this correctly if it is still just as fast. It just doesn't matter how you initialize the structure. Learn more about what the jitter optimizer does in this post .

+6
source

Your profiling code simplifies many things, but also makes the measurement pretty inaccurate. I would suggest using tools like BenchmarkDotNet to get more accurate results.

A quick test shows that direct assignments are a little faster, but nothing like 5x, you say:

 [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; } 
  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 | 

This is a 10% difference, not 5x.

+4
source

Source: https://habr.com/ru/post/1265059/


All Articles