Por alguna razón, parece que la operación Add
en un HashSet
es más lenta que la operación Contains
cuando el elemento ya existe en la HashSet
.rendimiento HashSet Añadir vs Contiene los elementos existentes
Aquí está la prueba:
Stopwatch watch = new Stopwatch();
int size = 10000;
int iterations = 10000;
var s = new HashSet<int>();
for (int i = 0; i < size; i++) {
s.Add(i);
}
Console.WriteLine(watch.Time(() =>
{
for (int i = 0; i < size; i++) {
s.Add(i);
}
}, iterations));
s = new HashSet<int>();
for (int i = 0; i < size; i++) {
s.Add(i);
}
// outputs: 47,074,764
Console.WriteLine(watch.Time(() =>
{
for (int i = 0; i < size; i++) {
if (!s.Contains(i))
s.Add(i);
}
}, iterations));
// outputs: 41,125,219
¿Por qué es más rápido que Contains
Add
de elementos ya existentes?
Nota: Estoy usando esta extensión Stopwatch
de otra pregunta.
public static long Time(this Stopwatch sw, Action action, int iterations) {
sw.Reset();
sw.Start();
for (int i = 0; i < iterations; i++) {
action();
}
sw.Stop();
return sw.ElapsedTicks;
}
ACTUALIZACIÓN: Las pruebas internas ha puesto de manifiesto que la gran diff rendimiento sólo ocurre en la versión de 64 bits del marco .NET. Con la versión de 32 bits del marco contiene Parece que se ejecuta a idéntica velocidad para agregar (de hecho, parece que la versión con el contenido ejecuta un porcentaje más lento en algunas ejecuciones de prueba) En las versiones X64 del marco, la versión con el contenido parece correr aproximadamente un 15% más rápido.
Para la prueba de 32 bits, ¿la ejecutó en una máquina de 32 bits, en una máquina virtual o especificando un objetivo x86 para la compilación y ejecutando el marco de 32 bits en WOW64? No sé si marcaría la diferencia, pero es posible. –
Realicé mi prueba de 32 bits en una VM –
¿Ha intentado mover la prueba de la función Contener Añadir encima de Agregar y luego medir el tiempo? Encontrará que la diferencia es insignificante. – Baz1nga