2010-12-10 14 views
6

Solo tengo curiosidad .. Cuando llamo Distinct <>() (desde Linq) en HashSet, ¿sabe .NET que este IEnumerable siempre contiene un conjunto de valores distintos, y optimiza esta llamada de distancia?Llamando a Distinct <>() en HashSet <T>

Respuesta

11

A juzgar por mirar el código a través de Reflector, tendría que decir que no.

El código termina construyendo una instancia de una clase generada por el método iterador, independientemente del tipo que le dé.

Este problema también se ve agravado por el hecho de que puede especificar objetos comparadores para Hashset y el método Distinct, lo que significa que la optimización solo se usará en muy pocos casos.

Por ejemplo, en el siguiente caso que en realidad podría optimizar la llamada de distancia, pero no sería capaz de saber que:

var set = new HashSet<int>(new MyOwnInt32Comparer()); 
var distinct = set.Distinct(new MyOwnInt32Comparer()); 

Desde que se dé dos instancias de la clase comparador y tal Por lo general, las clases no implementan métodos de igualdad, el método Distinct no tendría forma de saber que las dos implementaciones del comparador son realmente idénticas.

En cualquier caso, este es un caso en el que el programador sabe más sobre el código que el tiempo de ejecución, así que aprovéchelo. Linq puede ser muy bueno, pero no es omnipotente, así que utiliza tus conocimientos para tu ventaja.

+0

Gracias por su elaboración. – nothrow

2

Creo que no, porque la entrada de la clase Enumerable para el método distinto es IEnumerable y no hay nada específico para determinar que es un conjunto hash (por lo tanto, no haga nada).

2

No, mirando la implementación en reflector, no comprueba si la enumeración es HashSet<T>. El iterador subyacente crea un nuevo conjunto y lo rellena durante la enumeración, por lo que la sobrecarga no debería ser tan grande.

Cuestiones relacionadas