2009-07-30 7 views
1

Ok, j'ai un ensemble de très grands arbres identiques mis en mémoire (à renseigner avec des données non identiques [ils contiennent des informations à propos de choses à l'intérieur de chaque nœud]).Obtention d'une copie d'un grand objet (160000+ objet arborescence interne)

Je souhaite copier une seule instance de l'arborescence et remplir chaque copie avec un ensemble de données distinct. Cependant, pour l'instant, la copie en cache de l'arbre n'est pas copiée, mais simplement référencée et remplie avec chaque ensemble de données.

Comment puis-je forcer la méthode qui obtient l'arborescence vide mise en cache pour retourner une copie de l'objet, au lieu d'une référence?

+0

Quelles classes utilisez-vous pour gérer votre arborescence et que les classes prennent en charge l'interface ICloneable? –

+0

Il s'agit d'une classe arborescente personnalisée, construite à partir de zéro pour l'optimisation d'un problème de recherche/classification, et donc incroyablement légère pour la vitesse: chaque arbre contient plus de 160k nœuds, et c'est la version optimisée, l'implémentation naïve il rattrape plus de 10 fois ça. Ainsi, non, il n'est pas configuré pour prendre en charge icloneable. –

+1

J'ai lu les commentaires que vous avez postés sur les autres réponses ici et je pense que vous devez en clarifier certains. Vous dites que vous voulez une copie, mais vous dites qu'il serait plutôt fou de copier l'arbre d'origine. Qu'est-ce que tu veux faire exactement? Il n'y a pas de mécanisme dans .NET save pour que l'interface ICloneable fasse quelque chose comme ça, donc vous allez devoir écrire du code, peu importe ce que vous finissez avec. Quelle est exactement votre question ici? –

Répondre

2

Une alternative à Clone() - le sérialiser dans le flux binaire de la mémoire, puis le désérialiser en tant que nouvelle instance.

EDIT

En outre, si vous envisagerez sérialisation, et si la performance vous est principale préoccupation, s'il vous plaît prendre également en compte le test de performance suivant Manual Serialization 200% + Faster than BinaryFormatter.

+1

Si vous pensez que la sérialisation ou la copie récursive manuelle ne vous donnera pas les performances dont vous avez besoin, alors je suppose que vous devez utiliser le code non géré C++ pour pouvoir stocker efficacement votre arbre en mémoire et copier avec memcpy ...mais le code non managé ce n'est pas un domaine où je peux faire des suggestions très précieuses ... –

0

Il existe plusieurs façons, mais je recommande d'implémenter ICloneable sur l'objet arborescence, puis d'appeler le Clone() pour créer une copie profonde.

+0

En fait, l'implémentation d'ICloneable n'est généralement pas recommandée. –

+0

Une raison pour cela? Si je dois implémenter une copie profonde récursive, alors je préfère le faire avec une interface documentée. Comment implémenter le Clone() n'a pas d'importance, vous pouvez faire Object.MemberwiseCopy, utiliser la sérialisation ou assigner tous les champs vous-même – chris166

+0

@Chris: IClonable a manqué son but, donc c'est _no_longer_ recommandé. –

0

Je suggère de regarder de près vos classes d'arbres, et si vous allez appliquer la sémantique de copie, alors utilisez struct au lieu de classe. Sinon, utilisez l'interface ICloneable pour fournir la méthode Clone(), comme suggéré par chris166.

0

Avec un tel arbre, en avoir plusieurs copies entraînera beaucoup de frais généraux de mémoire. Pourquoi ne pas simplement organiser les données à chaque nœud (avec un dictionnaire, par exemple) afin qu'il contienne toutes les données différentes (comme vous le faites en ce moment), mais organisé d'une manière qui convient à vos besoins réels?

+0

la surcharge de mémoire est moins d'une préoccupation que la surcharge de traitement, dans ce cas. chaque nœud contient déjà un dictionnaire complet de données pour l'ensemble de données spécifique de l'arbre, l'ajout de ces données dans un autre dictionnaire serait trop de traitement lors de la génération de l'arbre. –

Questions connexes