2009-12-03 16 views
1

J'écris une classe pour représenter une ligne à partir d'une requête SQL. Je veux que les données de champ soient accessibles via la propriété indexer de la classe. C'est assez simple si je charge les données dans une liste interne d'objets. J'ai déjà essayé cela et je ne suis pas content de la boxe pour les primitifs. La boxe augmente l'exigence de mémoire de 20%. Je voudrais stocker les primitives en tant que primitives dans la classe. La classe DataTable stocke les primitives en créant des tableaux pour chaque colonne dans le schéma renvoyé par IDataReader. J'ai implémenté une classe de cette façon mais je préférerais que les données soient stockées avec l'objet row plutôt qu'avec une colonne référencée en interne par la ligne.Comment éviter le débockage de la mémoire de boxe lors de la lecture de lignes sql arbitraires

Des idées pour y parvenir?

Répondre

2

Vous pouvez générer un type de structure pour représenter une ligne. Cela peut être fait dynamiquement et il est possible de le faire pour qu'il n'y ait pas de boxe. Je ne suis pas sûr que cela soit digne de cet effort

+0

Pourquoi devrait-il s'agir d'un type de structure et non d'une classe? – Amnon

+0

+1 C'est une bonne idée mais comme vous le dites, je ne sais pas si je suis prêt à y aller pour le moment. Je vais d'abord essayer l'approche générique et si elle ne la coupe pas, j'essaierai de créer une structure interne dynamiquement. Merci – Steve

+0

@Reed - Je n'ai pas attrapé la boxe de la classe générique elle-même, vous avez raison. Cela ne sauverait pas la mémoire. – Steve

2

Seulement 20% de frais généraux? Tu es chanceux! J'ai juste nettoyé du code où il a ajouté une diminution de performance de quarante fois (sans compter l'impact de la mémoire supplémentaire)! Quoi qu'il en soit, la façon habituelle d'empêcher l'utilisation de object consiste à commencer à utiliser des génériques. Voici un exemple simplifié:

class RowRepresenter<T> 
{ 
    //.... 
    public T this[int index] {get; set;} // implementation left out 
} 

// initialize, suppose the properties (indexers) should be ints: 
RowRepresenter<int> myInstance = new RowRepresenter<int>(); 
myInstance.LoadData(); 

// get data (i.e., your indexer) 
int somefield = myInstance[2]; // no overhead, no casting required 
+0

Comment cela gère-t-il plusieurs types sur une seule ligne? –

+0

Vous avez parlé d'indexeurs. Vous avez soit un type par indexeur, soit vous ne l'avez pas. Si vous avez plusieurs types par indexeur, vous ne pouvez pas éviter d'utiliser la boxe, c'est le prix que vous payez pour ne pas utiliser la sécurité de type. Normalement, vous créez une classe qui correspond un peu à vos tables de données 1: 1. Les types correspondent alors aux types dans la base de données. En utilisant des génériques, vous pouvez supprimer certaines des parties les plus fastidieuses de l'utilisation des actions avec ces types, de sorte que vous n'avez pas besoin d'écrire les mêmes codes get-from-db et store-to-db encore et encore. C'est un scénario DAO typique. – Abel

+0

Désolé, le "vous" appliqué à Reed, je pensais que c'était Steve quand j'ai écrit la réponse au commentaire ;-) – Abel