我正在开发一个相当大规模的工程应用程序,它创建并处理结构的内存模型(从高层建筑到桥梁再到小屋子,什么都有)。该项目需要进行大量的几何分析和计算。为了支持此功能,该模型由许多微小的不可变只读结构组成,用于表示诸如点、线段等内容。这些结构中的某些值(例如点的坐标)在典型的程序执行期间会被访问数十万次甚至数百万次。由于模型的复杂性和计算量的巨大,性能非常关键。
我认为我们正在尽力优化算法、性能测试以确定瓶颈、使用正确的数据结构等等。我不认为这是过早优化的情况。性能测试表明,直接访问字段而不是通过对象的属性访问可以显著提高性能(至少一个数量级)。鉴于这些信息,以及我们还可以将相同的信息公开为属性来支持数据绑定和其他情况...这样做会有问题吗?请记住,这是不可变结构上的只读字段。有人能想到我将来会后悔吗?
下面是一个示例测试应用程序:
struct Point {
public Point(double x, double y, double z) {
_x = x;
_y = y;
_z = z;
}
public readonly double _x;
public readonly double _y;
public readonly double _z;
public double X { get { return _x; } }
public double Y { get { return _y; } }
public double Z { get { return _z; } }
}
class Program {
static void Main(string[] args) {
const int loopCount = 10000000;
var point = new Point(12.0, 123.5, 0.123);
var sw = new Stopwatch();
double x, y, z;
double calculatedValue;
sw.Start();
for (int i = 0; i < loopCount; i++) {
x = point._x;
y = point._y;
z = point._z;
calculatedValue = point._x * point._y / point._z;
}
sw.Stop();
double fieldTime = sw.ElapsedMilliseconds;
Console.WriteLine("Direct field access: " + fieldTime);
sw.Reset();
sw.Start();
for (int i = 0; i < loopCount; i++) {
x = point.X;
y = point.Y;
z = point.Z;
calculatedValue = point.X * point.Y / point.Z;
}
sw.Stop();
double propertyTime = sw.ElapsedMilliseconds;
Console.WriteLine("Property access: " + propertyTime);
double totalDiff = propertyTime - fieldTime;
Console.WriteLine("Total difference: " + totalDiff);
double averageDiff = totalDiff / loopCount;
Console.WriteLine("Average difference: " + averageDiff);
Console.ReadLine();
}
}
结果:
直接字段访问: 3262
属性访问: 24248
总差异: 20986
平均差异: 0.00020986
只需要21秒,何乐而不为呢?