C#の汎用インターフェイスはボクシングを防ぎますか? (.NET対Monoパフォーマンス)
-
02-07-2019 - |
質問
object
型として宣言された特定のメソッドパラメーターを持つC#インターフェイスがあります。ただし、実際に渡される型は、インターフェイスを実装するクラスによって異なる場合があります。
public interface IMyInterface
{
void MyMethod(object arg);
}
public class MyClass1 : IMyInterface
{
public void MyMethod(object arg)
{
MyObject obj = (MyObject) arg;
// do something with obj...
}
}
public class MyClass2 : IMyInterface
{
public void MyMethod(object arg)
{
byte[] obj = (byte[]) arg;
// do something with obj...
}
}
MyClass2の問題は、 byte []
と object
との間の変換がボックス化とボックス化解除。これらは、パフォーマンスに影響する計算負荷の高い操作です。
ジェネリックインターフェイスでこの問題を解決しますボクシング/アンボクシングを回避します
public interface IMyInterface<T>
{
void MyMethod(T arg);
}
public class MyClass1 : IMyInterface<MyObject>
{
public void MyMethod(MyObject arg)
{
// typecast no longer necessary
//MyObject obj = (MyObject) arg;
// do something with arg...
}
}
public class MyClass2 : IMyInterface<byte[]>
{
public void MyMethod(byte[] arg)
{
// typecast no longer necessary
//byte[] obj = (byte[]) arg;
// do something with arg...
}
}
これは、.NET対Monoでどのように実装されていますか?どちらのプラットフォームでもパフォーマンスに影響はありますか?
ありがとう!
解決
モノラルでどのように実装されているのかわかりませんが、コンパイラは使用されるさまざまなタイプごとに特定のタイプの新しい関数を作成するため、汎用インターフェイスが役立ちます(内部的には、同じものを利用できるいくつかのケースがあります生成された関数)。特定のタイプの関数が生成される場合、タイプをボックス化/ボックス化解除する必要はありません。
これが、Collections.Genericライブラリが.NET 2.0で大ヒットした理由です。これは、コレクションでボクシングが不要になり、効率が大幅に向上したためです。
他のヒント
Monoで.NETで行うのと同じ利点が得られます。
Genericsのサポートは1.9でのみ成熟したため、一般にMono 1.9またはMono 2.0 RCxを使用することを強くお勧めします。
MyClass2の問題は、 byte []との間の変換 オブジェクトはボクシングとアンボクシングです。 計算コストが高い パフォーマンスに影響する操作。
配列型に関連するボックス化はありません。値型要素を持つボックス化も含まれません。配列は参照型です。
(byte [])argのオーバーヘッドはせいぜい最小限です。
はい、.Net(MSはモノについて不明)ジェネリックはコンパイル時に実装されるため、ボックス化またはボックス化解除はまったく行われません。バックグラウンドでキャストを実行するだけの構文糖であるjavaジェネリックとは対照的です(少なくともこの方法は1回でした)。ジェネリックの主な問題は、ジェネリックコンテナを多態的に扱うことができないことですが、それはあなたのトピックから少し外れています:-)
Monoと話すことはできませんが、汎用インターフェイスを使用すると、MSランタイムのボクシング/アンボクシングの問題を解決する必要があります 。
モノの最新バージョンを使用している場合、可能であれば2.0。
Monoの一般的なインターフェイスのパフォーマンスは非常に良好で、通常のインターフェイスのディスパッチとペアになっています。
一般的な仮想メソッドのディスパッチ[1]は、リリースされたすべてのバージョンのmonoでひどいものであり、1.9時間で改善されました。
一般的な仮想メソッドのパフォーマンスの問題は、今年の終わりに予定されている次回のモノ(2.2)のリリースで修正されたため、問題はそれほど悪くありません。
[1]一般的な仮想メソッドは次のようなものです:
公開インターフェースFoo {
void Bla<T> (T a, T b);
}