Langsame Leistung von ImmutableList <T> Remove-Methode in Microsoft.Bcl.Immutable

Es ist eine unerwartete Leistung von Microsoft zu verzeichnenImmutableList aus dem NuGet-PaketMicrosoft.Bcl.Immutable Version 1.0.34 und auch 1.1.22-beta

Wenn Sie Elemente aus der unveränderlichen Liste entfernen, ist die Leistung sehr langsam. Für einImmutableList Enthält es 20000 Ganzzahlwerte (1 ... 20000), dauert es etwa 52 Sekunden, bis alle Elemente aus der Liste entfernt wurden, wenn der Wert 20000 auf 1 gesetzt wurde. Wenn ich das gleiche mit einem Generikum macheList<T> wo ich eine Kopie der Liste nach jedem Entfernungsvorgang erstelle, dauert es ungefähr 500 ms.

Ich war ein bisschen überrascht von diesen Ergebnissen, da ich das dachteImmutableList wäre schneller als ein generisches kopierenList<T>, aber vielleicht ist das zu erwarten?

Beispielcode
// Generic List Test
var genericList = new List<int>();

var sw = Stopwatch.StartNew();
for (int i = 0; i < 20000; i++)
{
    genericList.Add(i);
    genericList = new List<int>(genericList);
}
sw.Stop();
Console.WriteLine("Add duration for List<T>: " + sw.ElapsedMilliseconds);
IList<int> completeList = new List<int>(genericList);

sw.Restart();

// Remove from 20000 -> 0.
for (int i = completeList.Count - 1; i >= 0; i--)
{
    genericList.Remove(completeList[i]);
    genericList = new List<int>(genericList);
}
sw.Stop();
Console.WriteLine("Remove duration for List<T>: " + sw.ElapsedMilliseconds);
Console.WriteLine("Items after remove for List<T>: " + genericList.Count);


// ImmutableList Test
var immutableList = ImmutableList<int>.Empty;

sw.Restart();
for (int i = 0; i < 20000; i++)
{
    immutableList = immutableList.Add(i);
}
sw.Stop();
Console.WriteLine("Add duration for ImmutableList<T>: " + sw.ElapsedMilliseconds);

sw.Restart();

// Remove from 20000 -> 0.
for (int i = completeList.Count - 1; i >= 0; i--)
{
    immutableList = immutableList.Remove(completeList[i]);
}
sw.Stop();
Console.WriteLine("Remove duration for ImmutableList<T>: " + sw.ElapsedMilliseconds);
Console.WriteLine("Items after remove for ImmutableList<T>: " + immutableList.Count);
Aktualisieren

Wenn Sie Elemente vom Anfang der entfernenImmutableListWie bei einer normalen foreach-Schleife ist die Leistung gleichviel besser. Das Entfernen aller Elemente dauert dann weniger als 100 ms. Dies ist nicht in allen Szenarien möglich, kann aber gut zu wissen sein.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage