首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ConcurrentDictionary性能

ConcurrentDictionary性能
EN

Stack Overflow用户
提问于 2022-04-06 19:37:23
回答 2查看 816关注 0票数 2

我正在努力解决这个问题,希望能得到任何帮助。我在做一个现有的项目。我增加了计算值组合的逻辑,并确保我们没有通过某些限制。例如,给定此数据表列:

Name|Age|description

代码确保我们没有超过K组合的名称,年龄。我有一些数据,里面有上百万对像这样的东西。在某种程度上,程序只是崩溃,或卡住,虽然我没有看到任何内存问题或CPU问题。我使用元组的ConcurrentDictionary (名称、年龄)作为键实现了这个限制,我使用的是C# .NET 6。

我可以看到,尝试在DS中添加元素所花费的时间在某个时候变得非常长。

编辑:添加一些代码片段,虽然这是很多内部实现,但我确实认为这些是理解问题的主要代码部分:

下面是负责限制键的组件:

代码语言:javascript
复制
    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);
}

函数GetValueToLimit是为我的情况实现的:

代码语言:javascript
复制
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();
}

最后,下面是并发HashSet实现的一些部分:

代码语言:javascript
复制
    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;
        }
    }

其中concurrentHashSet是用C# concurrentDictionary实现的:

代码语言:javascript
复制
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);
    }

请分享任何有帮助的想法。

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-04-10 19:30:12

这是你的问题:

代码语言:javascript
复制
public override ConcurrentHashSetAddResult TryAdd(K element)
{
    if (Dictionary.Count() < _maxCapacity)
    {
        return base.TryAdd(element);
    }
    //...

...where Dictionary是底层ConcurrentDictionary<K, object>对象。

Count()是一个LINQ方法,它从开始到结束枚举可枚举的序列,或者在序列实现ICollection<TSource>接口时返回Count属性。ConcurrentDictionary<K, V>实现了这个接口,因此确实使用了Count属性。以下是这一财产的文件所说的话:

该属性具有快照语义,表示在访问属性时ConcurrentDictionary<TKey,TValue>中的项数。

“快照语义”是重要的部分。这意味着为了获得Count,字典必须暂时完全锁定。当线程读取Count时,所有其他线程都必须等待。根本没有并发性。

ApproximateCount属性在GitHub上的某个时候被提出了,但是它没有得到足够的支持,现在已经关闭了。该属性将允许您以更低的开销实现BoundConcurrentHashSet功能,但行为也不太准确:有可能超出_maxCapacity配置。

我的建议是放弃ConcurrentDictionary<K, object>,使用HashSet作为底层存储,由lock保护。

票数 2
EN

Stack Overflow用户

发布于 2022-04-18 18:07:39

我发现使用普通集合并在您要迭代和添加的位置使用锁比使用并发集合要快得多。添加到集合中的项目越多,这就成为事实。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71772684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档