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)
在下面的代码中,我使用自定义构造函数获得10秒
这不是需要10秒的代码,除非你有一台非常旧的机器.告诉我们你做错了什么,你正在运行未经优化的Debug构建或运行附带的调试器.不允许将内置于抖动中的优化器完成其工作的场景.
在代码周围循环运行10次,有助于摆脱启动开销和测量标准偏差,总是非常高速的代码就像这样.切换到发布版本并使用Ctrl + F5运行它.现在你得到了这段代码的实际性能,应该在1.5秒左右.这就是循环所花费的时间,优化器不会删除任何Point代码.它可以做什么,因为a变量没有在任何地方使用,构造函数没有可观察到的副作用.
让您想要完整删除的代码是典型的基准危险.您可以通过将a变量提升出循环并使用以下命令来防止这种情况发生:
Console.WriteLine("{0}", sw.ElapsedMilliseconds, a);
Run Code Online (Sandbox Code Playgroud)
现在优化器不再能消除Point代码,因为变量在循环之外使用.如果它仍然同样快,你就会知道你正在对它进行基准测试.如何初始化结构并不重要.更多关于抖动优化器在这篇文章中的作用.
您的分析代码简化了很多事情,但它也使得测量非常不准确.我建议使用像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倍.
| 归档时间: |
|
| 查看次数: |
436 次 |
| 最近记录: |