valores valor obtener new modificar llenar iterar ejemplos diccionario c# dictionary lookup

valor - new dictionary c#



¿Debo usar un diccionario de C#si solo necesito una búsqueda rápida de claves y los valores son irrelevantes? (2)

Puedes usar HashSet<T> .

La HashSet<T> proporciona operaciones de conjunto de alto rendimiento. Un conjunto es una colección que no contiene elementos duplicados y cuyos elementos no están en ningún orden en particular .

Necesito un tipo de datos que pueda insertar entradas y luego poder determinar rápidamente si ya se ha insertado una entrada. Un Dictionary parece satisfacer esta necesidad (ver ejemplo). Sin embargo, no tengo uso para los values del diccionario. ¿Debo seguir utilizando un diccionario o hay otro tipo de datos más adecuado?

public class Foo { private Dictionary<string, bool> Entities; ... public void AddEntity(string bar) { if (!Entities.ContainsKey(bar)) { // bool value true here has no use and is just a placeholder Entities.Add(bar, true); } } public string[] GetEntities() { return Entities.Keys.ToArray(); } }


La respuesta de Habib es excelente, pero para entornos de subprocesos múltiples si usa un HashSet<T> entonces, como consecuencia, tiene que usar lock para proteger el acceso a él. Me encuentro más propenso a crear interbloqueos con declaraciones de lock . Además, los lock producen una aceleración peor según la ley de Amdahl porque agregar una declaración de lock reduce el porcentaje de su código que es paralelo.

Por esas razones, un ConcurrentDictionary<T,object> ajusta a la factura en entornos de subprocesos múltiples. Si terminas usando uno, envuélvelo como lo hiciste en tu pregunta. Solo agregue new object para lanzarlos como valores según sea necesario, ya que los valores no serán importantes. Puede verificar que no haya declaraciones de lock en su código fuente .

Si no necesitas la mutabilidad de la colección, entonces esto sería discutible. Pero su pregunta implica que sí la necesita, ya que tiene un método AddEntity .

Información adicional 2017-05-19 - en realidad, ConcurrentDictionary usa los bloqueos internamente, aunque no las declaraciones de lock per se - usa Monitor.Enter (verifique el método TryAddInternal ). Sin embargo, parece que se bloquea en grupos individuales dentro del diccionario, lo que significa que habrá menos contención que poner todo en una declaración de lock .

Así que, en general, ConcurrentDictionary es a menudo mejor para entornos de múltiples subprocesos.

En realidad, es bastante difícil (¿imposible?) Hacer un conjunto de hash simultáneo utilizando solo los métodos de Interlocked . Lo intenté por mi cuenta y me encontré con el problema de tener que modificar dos cosas al mismo tiempo, algo que solo el bloqueo puede hacer en general. Una solución que encontré fue usar listas enlazadas individualmente para los cubos de hash y crear ciclos de forma intencional en una lista cuando se necesita un hilo para operar en un nodo sin interferencia de otros hilos; esto causaría que otros subprocesos quedaran atrapados dando vueltas en el mismo lugar hasta que el subproceso se hiciera con su nodo y deshiciera el ciclo. Claro, técnicamente no usaba cerraduras, pero no se escalaba bien.