C# 字符串比较的并行优化

C# 字符串比较的并行优化,c#,asynchronous,C#,Asynchronous,我试图优化用作数据库查询缓存的字典的每个字符串键上的字符串比较操作的性能。当前代码如下所示: public void Clear(string tableName) { foreach (string key in cache.Keys.Where(key => key.IndexOf(tableName, StringComparison.Ordinal) >= 0).ToList()) { cache.Remove(key); } } 我

我试图优化用作数据库查询缓存的字典的每个字符串键上的字符串比较操作的性能。当前代码如下所示:

public void Clear(string tableName)
{
    foreach (string key in cache.Keys.Where(key => key.IndexOf(tableName, StringComparison.Ordinal) >= 0).ToList())
    {
        cache.Remove(key);
    }
}

我对使用C#parallel特性不太熟悉,我想知道最好的方法是如何将其转换为并行操作,以便“同时”进行多个字符串比较。缓存通常会非常大,因此使用
Clear()
对其进行维护可能会非常昂贵。

将您的
缓存
对象设置为a,并使用
TryRemove
而不是
删除

这将使缓存线程安全;然后,可以像这样调用当前的
foreach
循环:

Parallel.ForEach(cache.Keys, key =>
{
    if(key.IndexOf(tableName, StringComparison.Ordinal) >= 0)
    {
        dynamic value; // just because I don't know your dictionary.
        cache.TryRemove(key, out value);
    }
});

希望这能为您提供一个起点。

您的方法不能在
字典上很好地工作,因为该类对于多个编写器来说不是线程安全的,因此同时删除可能会导致各种问题

因此,您必须使用锁来同步删除,从而使字典的访问基本上是单线程的。唯一可以跨线程同时安全完成的事情是
中的比较,其中

您可以使用
ConcurrentDictionary
,因为它使用条带锁将减少这种影响。不过,这似乎仍然不是最好的方法


如果您是从字符串构建键,以便测试键是否以子键开始,并且如果经常需要删除整个子键,那么您可以尝试使用
词典
。添加或更新变得有点昂贵,但清除变成了从更高级别的字典中只删除一个值的O(1)。

我以前使用字典作为缓存,我过去所做的是“动态”清理缓存,也就是说,在每个条目中我还包括它的包含时间,然后,每当请求条目时,我都会删除旧条目。性能影响对我来说是最小的,但如果需要,您可以实现一个队列(Tuple
,其中
TKey
是字典上的键的类型)作为保存这些时间戳的索引,这样您就不必每次迭代整个字典。不管怎样,如果你必须考虑这些问题,现在是考虑使用专用缓存服务器的时候了。对我来说,共享缓存()已经足够好了。

“缓存通常会变得相当大”-您有没有测量到性能瓶颈?如果没有,引入线程将一事无成并增加复杂性。如果我是你,我会首先考虑优化缓存方法,而不是并行化为其提供服务的代码。我运行过性能分析器,它告诉我70%的样本是在这个方法中采集的,特别是在IndexOf()中。不幸的是,由于现有框架的限制,我不得不使用这种缓存方法。我想对缓存中的元素数量施加一个上限,但这也不是一个选项。这可能比不使用线程的串行删除要慢。感谢您的响应。我尝试过这个,但它的执行速度确实比原始代码慢。不过我把它标记为答案,因为它最好地回答了我的问题,即使它没有解决我的问题。谢谢你的想法,但我负担不起任何额外的开销。什么样的额外开销?你的想法中有一个内在的开销,那就是试图并行清除。拆分查找的开销会对哪些方面产生影响?