Il seguente codice:Com'è possibile che "RemoveAll" in LINQ sia molto più veloce dell'iterazione?
List<Interval> intervals = new List<Interval>();
List<int> points = new List<int>();
//Initialization of the two lists
// [...]
foreach (var point in points)
{
intervals.RemoveAll (x => x.Intersects (point));
}
è almeno 100 volte più veloce di questo, quando le liste sono di dimensioni ~ 10000:
List<Interval> intervals = new List<Interval>();
List<int> points = new List<int>();
//Initialization of the two lists
// [...]
foreach (var point in points)
{
for (int i = 0; i < intervals.Count;)
{
if (intervals[i].Intersects(point))
{
intervals.Remove(intervals[i]);
}
else
{
i++;
}
}
}
Come è possibile? Cosa viene eseguito sotto il cofano con "RemoveAll"? Secondo MSDN, "RemoveAll" esegue una ricerca lineare ed è quindi in O (n). Quindi mi aspetterei prestazioni simili per entrambi.
Quando si sostituisce "Rimuovi" con "RimuoviAt", l'iterazione è molto più veloce, paragonabile a "Rimuovi tutto". Ma sia "Rimuovi" e "RimuoviAt" hanno complessità O (n), quindi perché la differenza di prestazioni tra loro è così grande? Potrebbe essere solo dovuto al fatto che "Rimuovi (elemento)" confronta gli elementi dell'elenco con "elemento" e "RimuoviAt" non esegue alcun confronto?
'RemoveAll' non usa LINQ, è un metodo standard su' Lista '. Ciò è notato dal fatto che 'RemoveAll' modifica la raccolta * in posizione * - LINQ non modifica le raccolte. –
Grazie per il chiarimento! Ho postato troppo veloce ... – Brainless
@Brainless, puoi accelerare il 2 ° esempio di codice, se usi 'intervalli.RimuoviAt (i);' invece di 'intervalli.Rimuovi (intervalli [i]);', penso. – ASh