Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

400
Views
Rendimiento de diccionario concurrente

Estoy luchando con este problema y realmente agradecería cualquier ayuda. Estoy trabajando en un proyecto existente. He agregado una lógica que cuenta las combinaciones de valores y se asegura de que no pasemos algún límite. Por ejemplo, dadas las columnas de esta tabla de datos:
Name|Age|description
El código se asegura de que no tengamos más de K combinaciones de Nombre, Edad. Tengo datos que contienen algo así como un millón de pares como este. En algún momento, el programa simplemente falla o se atasca, aunque no veo ningún problema de memoria o de CPU. Implementé este límite usando ConcurrentDictionary of tuplas (Name, Age) como claves, y estoy usando C# .NET 6 ..
Puedo ver que el tiempo que lleva intentar agregar un elemento al DS se vuelve realmente largo en algún momento.

Editar: agregar algunas piezas de código, aunque es una gran cantidad de implementación interna, creo que estas son las partes principales del código para comprender el problema:

aquí está el componente que es responsable de limitar las claves:

 protected override Result Process(Row row) { var valueToLimit = GetValueToLimit(row); var result = _values.TryAdd(valueToLimit); } // some logic related to the case of crossing the limit return Result.Success; } protected abstract T GetValueToLimit(Row row); }

La función GetValueToLimit está implementada para mi caso:

 protected override string[] GetValueToLimit(Row row) { // takes the relevant values from an input record, according to the requested columns. return _columnIndices.Select(x => row.GetValue(x)).ToArray(); }

y finalmente, aquí hay algunas partes de la implementación simultánea de HashSet:

 public class BoundedConcurrentHashSet<K> : ConcurrentHashSet<K> { .. public override Result TryAdd(K element) { if (Dictionary.Count() < _maxCapacity) { return base.TryAdd(element); } else { return Contains(element) ? Result.AlreadyInHash : Result.ExceedsCapacity; } }

donde concurrentHashSet se implementa con C# concurrentDictionary:

 public class ConcurrentHashSet<K> { public ConcurrentHashSet(IEqualityComparer<K> equalityComparer) { Dictionary = new ConcurrentDictionary<K, object>(equalityComparer); } protected ConcurrentDictionary<K, object> Dictionary { get; } public int Count => Dictionary.Count; public IEnumerable<K> Elements => Dictionary.Keys; public virtual Result TryAdd(K element) { return Dictionary.TryAdd(element, null) ? dResult.Added : Result.AlreadyInHash; } public bool Contains(K element) { return Dictionary.ContainsKey(element); }

Por favor, comparta cualquier idea que pueda ayudar.

Gracias

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Aquí está tu problema:

 public override ConcurrentHashSetAddResult TryAdd(K element) { if (Dictionary.Count() < _maxCapacity) { return base.TryAdd(element); } //...

...donde Dictionary es el ConcurrentDictionary<K, object> subyacente.

Count() es un método LINQ que enumera la secuencia enumerable de principio a fin o devuelve la propiedad Count en caso de que la secuencia implemente la ICollection<TSource> . El ConcurrentDictionary<K, V> implementa esta interfaz, por lo que la propiedad Count se usa de hecho. Esto es lo que dice la documentación de esta propiedad :

Esta propiedad tiene una semántica de instantánea y representa la cantidad de elementos en ConcurrentDictionary<TKey,TValue> en el momento en que se accedió a la propiedad.

La "semántica instantánea" es la parte importante. Significa que para adquirir el Count , el diccionario debe estar completamente bloqueado temporalmente. Cuando un subproceso lee Count , todos los demás subprocesos tienen que esperar. Sin concurrencia en absoluto.

En algún momento se propuso una propiedad ApproximateCount en GitHub, pero no tuvo suficiente tracción y ahora está cerrada. Esa propiedad le permitiría implementar la funcionalidad BoundConcurrentHashSet con una sobrecarga muy reducida, pero también con un comportamiento menos preciso: sería posible superar la configuración de _maxCapacity .

Mi sugerencia es deshacerse de ConcurrentDictionary<K, object> y usar un HashSet<T> como almacenamiento subyacente, protegido con un lock .

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!