Effiziente Weise zu Klonen, eine HashSet<T>?

Vor ein paar Tagen antwortete ich eine interessante Frage auf SO über HashSet<T>. Eine mögliche Lösung beteiligt Klonen der hashset, und in meiner Antwort habe ich vorgeschlagen, so etwas zu tun:

HashSet<int> original = ...
HashSet<int> clone = new HashSet<int>(original);

Obwohl dieser Ansatz ist Recht einfach, ich vermute, es ist sehr ineffizient: der Konstruktor der neuen HashSet<T> muss separat hinzufügen jedes Element aus der original-hashset, und überprüfen, wenn es nicht bereits vorhanden. Dies ist eindeutig eine Verschwendung von Zeit: da die source-Sammlung ist ein ISet<T> es garantiert keine Duplikate enthalten. Es sollte eine Weise zu nutzen, dass wissen...

Idealerweise HashSet<T> umsetzen sollte ICloneable, aber leider ist es nicht der Fall. Ich habe auch überprüft, mit Reflektor, um zu sehen, wenn die HashSet<T> Konstruktor hat etwas besonderes, wenn die source-Sammlung war ein hashset, aber es funktioniert nicht. Es konnte wahrscheinlich gemacht werden, mithilfe von reflektion auf private Felder, aber das wäre ein hässlicher hack,...

Also, hat jemand kommen mit eine clevere Lösung, die zum Klonen eines hashset effizienter ?

(Hinweis: diese Frage ist rein theoretisch, ich brauche das nicht zu tun, dass in einem realen Programm)

  • hm, gute Frage, aber einfach nur neugierig, was sind die theoretischen Ineffizienzen sind wir besorgt? ich bin eingerostet auf meine Bestellung notation für abstrakte Daten-Typen, aber hätte es nicht auch ein check auf die Existenz innerhalb der Ziel-hash gesetzt werden, eine einfache O(1) - Kollision-test? ich bin damit einverstanden von einer Informations-Perspektive, könnte es "besser", aber können wir eine Schranke für es, und wäre es von Bedeutung?
  • Ich vermute, Sie haben nicht ein HashSet<T>(ISet<T>) - Konstruktor ist, da jede Klasse umsetzen konnte ISet<T>, vielleicht schlecht; was bedeutet, dass die Anwesenheit von ISet<T> ist keine Garantie dafür, dass keine Duplikate vorhanden sind
  • Ellinger, du hast wahrscheinlich Recht. Jedoch, Sie könnte ein HashSet<T>(HashSet<T>) - Konstruktor...
  • Eigentlich ist das, was ich bin neugierig ist, warum Sie nicht ICloneable implementieren, ist es, weil eine Umsetzung wäre nicht mehr effizient dann der Konstruktor Sie endete Aufruf in Ihrem Sinne zu beantworten; also, warum die Mühe, wenn die Funktionalität bereits verfügbar. Das gleiche könnte möglicherweise sein, sagte für Ihre Kopie-Konstruktor. Natürlich scheint dies nicht plausibel angesichts Ihrer Bemerkung über 'und überprüfen Sie, wenn es nicht bereits vorhanden ist'. Hmmm.
  • Auch die deserializer macht keine Annahmen und verwendet AddIfNotPresent(). Gute Idee, die Kultur verändert haben könnte. Dies ist ein no-go. Frage zum Klonen der ersten. Kostspielig sein sollte, gut, teuer. Große API-design.
  • Würden Sie geschehen, zu wissen, der alle Strafen der Verwendung der Serialisierung im Allgemeinen? Getestet habe ich dies vergleichen mit dem Konstruktor vs serialisieren und der Konstruktor war fast 2x schneller im Durchschnitt, ohne überprüfung (3x mit Verifizierung) auf 10000 Punkt gesetzt. Bei größeren Mengen wird der Unterschied verringert sich mit Konstruktor noch schneller. Ich kann nach dem code, wenn Sie möchten.
  • g, ich habe gerade einen kleinen test: Klon mit der spiegelung vs. Konstruktor-Aufruf. Auch mit dem Aufwand es bedeutet, die Reflexion ist in etwa doppelt so schnell. Also ich denke, ein echter Clone-Methode wäre viel schneller...
  • Passant, gute Erläuterungen. In Bezug auf die Notwendigkeit der Klon ein hashset: wie gesagt, die Frage ist rein theoretisch, ich brauche nicht, es zu tun.
  • M die Idee der Verwendung der Serialisierung in den Sinn gekommen, aber ich bedeutet, dass (1) die Objekte müssen serialisierbar sein sollen, und (2) jedes Element wird geklont... Meine Idee war es, eine flache Kopie des hashset, nicht eine Tiefe Kopie.
  • Sie hat nicht ICloneable implementieren, weil es eine miese interface. blogs.msdn.com/b/brada/archive/2003/04/09/49935.aspx ist ein Grund.
  • warum würden Sie denken, Sie haben nicht einige effiziente Art und Weise der Umsetzung der Klon über den Konstruktor? Wenn ich das schreiben von code, id-überprüfen Sie die Eingabe, und wenn ich wusste, dass das übergebene Objekt war ein HashSet<T>, dann könnte ich schreiben, eine spezielle,schnellere Methode zu tun, die Kopie,da kann ich ableiten, - Informationen aus diesen, und auch den Zugriff auf die Geschlechtsteile der input-andere HashSet<T>, sonst nur eine "langsame" kopieren
  • Ich überprüfte den code, mit Reflektor, gibt es keine solche Optimierung.
  • Levesque: keine überraschung, nehme ich an, aber es ist sicherlich eine Optimierung gemacht werden könnte. wie du oben gesagt, es ist ziemlich ineffizient, neu berechnen, etwas, das Sie bereits Zugriff haben, und ich kann nicht denken, der aus irgendeinem Grund nicht zu. dann wieder, wenn Ihr geht zu tun, dass es besser wäre, um eine HashSet<T>(HashSet<T>) - Konstruktor, wie Sie sagte.

Schreibe einen Kommentar