pelea - ¿Las interfaces genéricas en C#previenen el boxeo?(.NET vs rendimiento mono)
la pelea de esta noche (6)
El problema con MyClass2 es que la conversión de byte [] en y desde un objeto es boxeo y unboxing, que son operaciones costosas desde el punto de vista informático que afectan el rendimiento.
No hay boxeo involucrado con los tipos de matriz, incluso uno con elementos de tipo de valor. Una matriz es un tipo de referencia.
La sobrecarga (byte []) arg es mínima en el mejor de los casos.
Tengo una interfaz C # con ciertos parámetros de método declarados como tipos de object
. Sin embargo, el tipo real pasado puede variar según la clase que implementa la interfaz:
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...
}
}
El problema con MyClass2 es que la conversión de byte[]
en y desde un object
es boxeo y unboxing , que son operaciones costosas desde el punto de vista informático que afectan el rendimiento.
¿Resolvería este problema con una interfaz genérica evitar el boxeo / 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...
}
}
¿Cómo se implementa esto en .NET vs Mono? ¿Habrá implicaciones de rendimiento en cualquiera de las plataformas?
¡Gracias!
No estoy seguro de cómo se implementa en mono, pero las interfaces genéricas ayudarán porque el compilador crea una nueva función del tipo específico para cada tipo diferente utilizado (internamente, hay algunos casos donde puede utilizar la misma función generada) . Si se genera una función del tipo específico, no hay necesidad de box / unbox el tipo.
Esta es la razón por la cual la biblioteca Collections.Generic fue un gran éxito en .NET 2.0 porque las colecciones ya no requieren del boxeo y se vuelven significativamente más eficientes.
No puedo hablar con Mono, pero usar una interfaz genérica debería resolver el problema del boxeo / unboxing en el tiempo de ejecución de MS.
Obtendrá los mismos beneficios en Mono que en .NET.
Recomendamos encarecidamente que utilice Mono 1.9 o Mono 2.0 RCx en general, ya que la compatibilidad con genéricos solo ha madurado con 1.9.
Dado que estás usando una versión reciente de mono, 2.0 si puedes.
El rendimiento genérico de la interfaz en Mono es muy bueno, en pares con despacho de interfaz regular.
El envío de métodos virtuales genéricos [1] es terrible en todas las versiones de mono lanzadas, ha mejorado en 1.9 miles.
El problema no es tan malo, ya que el problema de rendimiento con los métodos virtuales genéricos se ha solucionado para la próxima versión de mono (2.2), que está programada para finales de este año.
[1] Un método virtual genérico es algo así como:
interfaz pública Foo {
void Bla<T> (T a, T b);
}
Sí, en .NET (MS no está seguro acerca de los mono) genéricos se implementan en tiempo de compilación, por lo que no hay boxeo o unboxing en absoluto. En contraste con los genéricos de java que son azúcar sintáctico que simplemente realizan los moldes para usted en el fondo (al menos así fue una vez). El principal problema con los genéricos es que no puedes tratar los contenedores genéricos de forma polimórfica, pero eso está un poco fuera de tu tema :-)