我试图通过将 double 包装到结构中来获得我所谓的测量单位系统。我有 C# 结构,如 Meter、Second、Degree 等。我最初的想法是,在编译器被内联后,我将获得与使用 double 相同的性能。
我的显式和隐式运算符简单明了,编译器实际上内联了它们,但是使用 Meter 和 Second 的代码比使用 double 的相同代码慢 10 倍。
我的问题是:如果 C# 编译器无论如何都内联所有内容,为什么不能使使用 Second 的代码与使用 double 的代码一样优化?
二是定义如下:
struct Second
{
double _value; // no more fields.
public static Second operator + (Second left, Second right)
{
return left._value + right._value;
}
public static implicit Second operator (double value)
{
// This seems to be faster than having constructor :)
return new Second { _value = value };
}
// plenty of similar operators
}
更新:
我没有问 struct 是否适合这里。确实如此。
我没有问代码是否会被内联。JIT 确实内联它。
我检查了运行时发出的汇编操作。对于这样的代码,它们是不同的:
var x = new double();
for (var i = 0; i < 1000000; i++)
{
x = x + 2;
// Many other simple operator calls here
}
像这样:
var x = new Second();
for (var i = 0; i < 1000000; i++)
{
x = x + 2;
// Many other simple operator calls here
}
反汇编中没有调用指令,因此操作实际上是内联的。然而,差异是显着的。性能测试表明,使用 Second 比使用 double 慢 10 倍。
所以我的问题是(注意!):为什么 JIT 生成的 IA64 代码与上述情况不同?可以做些什么来让 struct 以双倍的速度运行?double 和 Second 之间似乎没有理论上的区别,我看到的差异的深层原因是什么?