如果我有一个ConcurrentDictionary实例,那么我是使用Count属性还是使用LINQ的Any()是否重要?我宁愿写dict.Any()而不是dict.Count > 0,因为我认为Any()更具有描述性。
我只关心正确性,而不是性能。用例是
void process()
{
if (concurrentDictionary.Count <= 0) // or !Any() ?
return; // dictionary is empty, nothing to do
// ...
}发布于 2015-04-01 19:57:02
IEnumerable Linq方法线程安全吗?的问题解决了这样一个事实:如果没有保护集合的特定锁,LINQ查询上的IEnumerable方法就不是线程安全的。
您可以查看ConcurrentDictionary参考代码,以了解枚举数没有提供线程安全快照。另外,ConcurrentDictionary.GetEnumerator的MSDN文档声明:
从字典返回的枚举器与读和写字典同时使用是安全的,但是它并不表示字典的即时快照。通过枚举数公开的内容可能包含在调用GetEnumerator之后对字典所做的修改。
Count属性对字典进行完全锁定,并返回一致的结果。
因此,取决于您是否希望在字典上使用锁来运行Any(),检查Count > 0可能更简单。
发布于 2015-04-01 19:41:06
您将不得不对它们进行基准测试,因为Any()类似于
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
if (enumerator.MoveNext())
{
return true;
}
}
return false;因此,它需要枚举,对于ConcurrentDictionary来说,这是一件复杂的事情,但即使是Count of ConcurrentDictionary也没有缓存,而且看起来相当复杂。
我要补充的是,Count仍然必须遍历一些内部结构(如数组中的那样),查询整个字典上的锁,而Any()将在第一个非空桶处停止。我要说的是,对于一个大字典,Count更慢,而对于一个小字典,它更快。
更正:Count在计数前对所有字典都有一个锁。它确实叫this.AcquireAllLocks()。
请记住,这两种方法的结果可能会在方法返回之前被篡改,因为.并发!:)
发布于 2015-04-01 19:36:22
我是使用
Count属性还是LINQ的Any()?
不是的。它们在功能上是相同的,它们的性能差别应该很小。使用任何传达最恰当的含义的东西,只有当性能问题对整个应用程序的性能有重大影响时,才可以更改它。
Count将在调用该属性时对字典中的项进行计数。
Any将调用ConcurrentDictionary.GenEnumerator(),以查看字典中是否有任何项。根据文档,返回的枚举数将在调用GetEnumerator()后对字典进行反映和更改。
因此,从理论上讲,如果在调用Any和在Any中调用MoveNext之间添加了一个项,那么它们的计数得到不同的答案是可能的。然而,时间窗应该是如此之短,希望应该很小。
再加上谁能说哪个是对的?如果可以在添加项的同时使用Any和Count,则集合是否为空?
https://stackoverflow.com/questions/29399256
复制相似问题