double を構造体にラップすることで、私が測定単位系と呼ぶものを取得しようとしています。私は Meter、Second、Degree などの C# 構造を持っています。私の最初のアイデアは、コンパイラがすべてをインライン化した後、double を使用した場合と同じパフォーマンスが得られるというものでした。
私の明示的および暗黙的な演算子はシンプルで単純であり、コンパイラは実際にそれらをインライン化しますが、Meter と Second を使用したコードは double を使用した同じコードよりも 10 倍遅くなります。
私の質問は次のとおりです。とにかくすべてをインライン化する場合、C# コンパイラが Second を使用するコードを double を使用するコードと同じくらい最適化できないのはなぜですか?
2 番目は次のように定義されます。
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
}
アップデート:
構造体がここに収まるかどうかは尋ねませんでした。します。
コードがインライン化されるかどうかは尋ねませんでした。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
}
逆アセンブルには call 命令がなかったので、操作は実際にはインライン化されていました。それでも、違いは重要です。パフォーマンス テストでは、Second を使用すると、double を使用するよりも 10 倍遅くなることが示されています。
私の質問は (注意!): JIT で生成された IA64 コードが上記のケースと異なるのはなぜですか? 構造体を倍速で実行するにはどうすればよいですか? double と Second の間に理論的な違いはないようですが、私が見た違いの深い理由は何ですか?