Ich stolperte über das folgende Problem.
Ich möchte ein hashset mit allen Zahlen von 1 bis 100.000.000. Ich habe versucht, den folgenden Code:Was macht ein Hashset beim Initialisieren einer Sammlung mit Speicher?
var mySet = new HashSet<int>();
for (var k = 1; k <= 100000000; k++)
mySet.Add(k);
Dieser Code machen es nicht, da ich einen Speicherüberlauf rund um die 49mil irgendwo bekam. Das war auch ziemlich langsam und das Gedächtnis wuchs übermäßig.
Dann habe ich das versucht.
var mySet = Enumerable.Range(1, 100000000).ToHashSet();
wo ToHashSet() ist der folgende Code:
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> source)
{
return new HashSet<T>(source);
}
ich wieder einen Speicherüberlauf bekam aber ich konnte mehr Zahlen setzen in dann mit dem vorherigen Code.
Die Sache, die Arbeit tut, ist die folgende:
var tempList = new List<int>();
for (var k = 1; k <= 100000000; k++)
tempList.Add(k);
var numbers = tempList.ToHashSet();
Es dauert etwa 800 ms auf meinem System nur den tempList zu füllen, wo die Enumerable.Range() nur 4 Ticks nimmt!
Ich brauche diese HashSet oder sonst würde es zu viel Zeit brauchen, um Werte zu suchen (ich brauche es O (1)) und es wäre toll, wenn ich das am schnellsten machen könnte.
Nun ist meine Frage:
Warum verursachen die ersten beiden Methoden einen Speicherüberlauf, wo die dritte nicht?
Gibt es etwas spezielles HashSet mit dem Speicher beim Initialisieren?
Mein System hat 16GB Speicher, so dass ich ziemlich überrascht war, als ich die Überlauf-Ausnahmen bekam.
an Eine Sache zu beachten ist, dass "Enumerable.Range" ist so schnell, weil es tatsächlich nichts generiert, wenn Sie es ausführen. Nur wenn es benutzt wird (zB im 'ToHashSet'-Aufruf), beginnt es tatsächlich, Zahlen zu erzeugen. – Chris
@Chris Wusste das nicht. Vielen Dank :). – Mixxiphoid
Es ist das gleiche mit allen aufzählbaren Sachen Linq Typ. Wenn Sie ein Where in einem Enumerable oder Select oder eine beliebige Anzahl anderer Dinge gemacht haben, die im Wesentlichen mehr Iserables liefern, wird die Ausführung verzögert, bis sie verwendet werden. Es ist nützlich, dies zu wissen, da Sie aufgrund dieses Verhaltens einige Fehler haben können (obwohl ich von einem kurzen Beispiel keine Ahnung habe). – Chris