C#中的通用接口是否可以防止拳击? (.NET vs Mono性能)
-
02-07-2019 - |
题
我有一个C#接口,其中某些方法参数声明为 object
类型。但是,传递的实际类型可能因实现接口的类而异:
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 vs Mono中实现的?这两个平台都会有任何性能影响吗?
谢谢!
解决方案
我不确定它是如何在单声道中实现的,但是通用接口将有所帮助,因为编译器为每种使用的不同类型创建特定类型的新函数(在内部,有一些情况下它可以使用相同的生成函数)。如果生成特定类型的函数,则无需对该类型进行装箱/取消装箱。
这就是Collections.Generic库在.NET 2.0中受到重创的原因,因为集合不再需要装箱而且效率明显提高。
其他提示
您将在Mono中获得与.NET相同的好处。
我们强烈建议您一般使用Mono 1.9或Mono 2.0 RCx,因为泛型支持仅适用于1.9。
MyClass2的问题在于 byte []的转换和转换 对象是装箱和拆箱,哪个 计算上很昂贵 影响绩效的行动。
数组类型不涉及装箱,即使是具有值类型元素的装箱也是如此。数组是引用类型。
(byte [])arg上的开销最多是最小的。
是的,在.Net(MS不确定单声道)泛型是在编译时实现的,因此根本没有装箱或拆箱。与java泛型相比,这是一种语法糖,它只是在后台为你执行演员表(至少它是这样的一次)。泛型的主要问题是你不能多态地处理泛型容器,但这有点偏离你的主题: - )
我无法与Mono通话,但使用通用接口应该解决MS运行时中的装箱/拆箱问题。
鉴于您使用的是最新版本的mono,如果可以,请使用2.0。
Mono上的通用接口性能非常好,与常规接口调度配对。
发布通用虚拟方法[1]在所有已发布的mono版本上都很糟糕,它在1.9版本中有所改进。
问题并不是那么糟糕,因为通用虚拟方法的性能问题已经针对下一版的mono(2.2)进行了修复,该版本计划在今年年底完成。
[1]通用虚拟方法类似于:
public interface Foo {
void Bla<T> (T a, T b);
}