C# 中的通用接口会阻止装箱吗? (.NET 与 Mono 性能对比)
我有一个 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 与 Mono 中是如何实现的? 这两个平台上都会有性能影响吗?
谢谢你!
I have a C# interface with certain method parameters declared as object
types. However, the actual type passed around can differ depending on the class implementing the interface:
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...
}
}
The problem with MyClass2 is that the conversion of byte[]
to and from object
is boxing and unboxing, which are computationally expensive operations affecting performance.
Would solving this problem with a generic interface avoid boxing/unboxing?
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...
}
}
How is this implemented in .NET vs Mono? Will there be any performance implications on either platform?
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您将在 Mono 中获得与 .NET 中相同的好处。
我们强烈建议您一般使用 Mono 1.9 或 Mono 2.0 RCx,因为泛型支持仅在 1.9 时成熟。
You will get the same benefits in Mono that you do in .NET.
We strongly recommend that you use Mono 1.9 or Mono 2.0 RCx in general, as generics support only matured with 1.9.
我无法与 Mono 对话,但使用通用接口应该解决 MS 运行时中的装箱/拆箱问题。
I can't speak to Mono, but using a generic interface should solve the boxing/unboxing issue in the MS runtime.
假设您使用的是最新版本的 mono,如果可以的话,请使用 2.0。
Mono 上的通用接口性能非常好,与常规接口调度配对。
通用虚拟方法的调度[1]在所有已发布的 Mono 版本上都很糟糕,它在 1.9 中得到了改进。
这个问题并没有那么严重,因为通用虚拟方法的性能问题已经在下一版 Mono (2.2) 中得到解决,该版本计划于今年年底发布。
[1] 通用虚拟方法类似于:
public interface Foo {
}
Given you're using a recent version of mono, 2.0 if you can.
Generic interface performance on Mono is very good, on pair with regular interface dispatch.
Dispatch of generic virtual methods[1] is terrible on all released versions of mono, it has improved in 1.9 thou.
The problem is not that bad as the performance issue with generic virtual methods has been fixed for the next release of mono (2.2), which is scheduled to the end of this year.
[1] A generic virtual method is something like:
public interface Foo {
}
是的,在.Net(微软不确定单声道)中,泛型是在编译时实现的,因此根本没有装箱或拆箱。 与 Java 泛型相反,Java 泛型是语法糖,只是在后台为您执行强制转换(至少曾经是这样)。 泛型的主要问题是你不能多态地处理泛型容器,但这有点偏离你的主题:-)
Yes, in .Net (MS not sure about mono) generics are implemented at compile time so there is no boxing or unboxing going on at all. Contrast to java generics which are syntactic sugar that just perform the casts for you in the background (at least it was this way once). The main problem with generics is you can't treat generic containers polymorphically, but that is a bit off your topic :-)
我不确定它是如何在单声道中实现的,但是通用接口会有所帮助,因为编译器为使用的每种不同类型创建特定类型的新函数(在内部,有一些情况它可以利用相同的生成函数) 。 如果生成了特定类型的函数,则无需对该类型进行装箱/拆箱。
这就是 Collections.Generic 库在 .NET 2.0 中大受欢迎的原因,因为集合不再需要装箱并且变得更加高效。
I'm not sure how it is implemented in mono, but generic interfaces will help because the compiler creates a new function of the specific type for each different type used (internally, there are a few cases where it can utilize the same generated function). If a function of the specific type is generated, there is no need to box/unbox the type.
This is why the Collections.Generic library was a big hit at .NET 2.0 because collections no longer required boxing and became significantly more efficient.
数组类型不涉及装箱,即使是值类型元素也是如此。 数组是引用类型。
(byte[]) arg 上的开销最多是最小的。
There is no boxing involved with array types, even one with value type elements. An array is a reference type.
The overhead on (byte[]) arg is minimal at best.