Question

J'ai une interface C # avec certains paramètres de méthode déclarés comme types object . Cependant, le type réel transmis peut varier en fonction de la classe implémentant l'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...
    }
}

Le problème avec MyClass2 est que la conversion de octet [] en objet est boxe et déballage , qui sont des opérations coûteuses en termes de calcul qui affectent les performances.

Résoudre ce problème avec une interface générique évite la boxe / 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...
    }
}

Comment cela est-il implémenté dans .NET vs Mono? Y aura-t-il des conséquences en termes de performances sur l’une ou l’autre des plateformes?

Merci!

Était-ce utile?

La solution

Je ne sais pas comment cela est mis en œuvre en mono, mais les interfaces génériques vous aideront, car le compilateur crée une nouvelle fonction du type spécifique pour chaque type utilisé (en interne, il existe quelques cas où il peut utiliser la même fonction générée). Si une fonction du type spécifique est générée, il n'est pas nécessaire de cocher / dé-coller le type.

C’est la raison pour laquelle la bibliothèque Collections.Generic a été un franc succès pour .NET 2.0 car les collections n’ont plus besoin de boxe et sont devenues nettement plus efficaces.

Autres conseils

Vous obtiendrez les mêmes avantages dans Mono que dans .NET.

Nous vous recommandons vivement d'utiliser Mono 1.9 ou Mono 2.0 RCx en général, car la prise en charge des génériques n'est arrivée à maturité qu'avec la version 1.9.

  

Le problème avec MyClass2 est que le   conversion d'octet [] vers et depuis   objet est la boxe et unboxing, qui   sont coûteux en calcul   opérations affectant les performances.

Il n'y a pas de boxe impliquée dans les types de tableaux, même avec des éléments de type valeur. Un tableau est un type de référence.

La surcharge sur (byte []) arg est au mieux minimale.

Oui, dans .Net (MS n'est pas sûr du mono), les génériques sont implémentés au moment de la compilation, il n'y a donc pas de boxing ou de déballage. Contrastez-vous avec les génériques Java qui sont du sucre syntaxique et réalisent les moulages pour vous en arrière-plan (du moins c'était comme ça une fois). Le principal problème des génériques est que vous ne pouvez pas traiter les conteneurs génériques de manière polymorphe, mais cela vous échappe un peu: -)

Je ne peux pas parler à Mono, mais l'utilisation d'une interface générique devrait résoudre le problème de la boxe / de la déballage dans le moteur d'exécution de Microsoft.

Étant donné que vous utilisez une version récente de mono, la version 2.0 si vous le pouvez.

Les performances d’interface générique sur Mono sont très bonnes, avec une distribution d’interface régulière.

L’envoi de méthodes virtuelles génériques [1] est terrible pour toutes les versions publiées de mono, il s’est amélioré de 1,9%.

Le problème n’est pas si grave car le problème de performances des méthodes virtuelles génériques a été résolu pour la prochaine version de mono (2.2), prévue pour la fin de cette année.

[1] Une méthode virtuelle générique est quelque chose comme:

interface publique Foo {

  void Bla<T> (T a, T b);

}

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top