【发布时间】:2019-11-24 10:01:15
【问题描述】:
我想在多线程环境中测量并发字典与字典+锁的性能。所以我创建了自己的类型为<int,int[]> 的 SyncDict 类。每当有键匹配时,它会将int[] 数组值添加到自身,并在更新值时使用 ReaderWriterLockSlim 锁定整个字典。
我通过并发字典复制了代码,我主要使用AddOrUpdate()方法。
整个控制台应用程序代码可以在这里找到https://dotnetfiddle.net/1kFbGy 只需将代码复制粘贴到控制台应用程序中即可运行。它不会运行小提琴
使用相同的输入运行两个代码后,我发现运行时间存在很大差异。例如,对于我的机器上的一次特定运行,并发字典耗时 4.5 秒,而 SyncDict 耗时不到 1 秒。
我想知道解释上述运行时间的任何想法/建议。我在这里有什么问题吗。
class SyncDict<TKey>
{
private ReaderWriterLockSlim cacheLock;
private Dictionary<TKey, int[]> dictionary;
public SyncDict()
{
cacheLock = new ReaderWriterLockSlim();
dictionary = new Dictionary<TKey, int[]>();
}
public Dictionary<TKey, int[]> Dictionary
{
get { return dictionary; }
}
public int[] Read(TKey key)
{
cacheLock.EnterReadLock();
try
{
return dictionary[key];
}
finally
{
cacheLock.ExitReadLock();
}
}
public void Add(TKey key, int[] value)
{
cacheLock.EnterWriteLock();
try
{
dictionary.Add(key, value);
}
finally
{
cacheLock.ExitWriteLock();
}
}
public AddOrUpdateStatus AddOrUpdate(TKey key, int[] value)
{
cacheLock.EnterUpgradeableReadLock();
try
{
int[] result = null;
if (dictionary.TryGetValue(key, out result))
{
if (result == value)
return AddOrUpdateStatus.Unchanged;
else
{
cacheLock.EnterWriteLock();
try
{
Parallel.For(0, value.Length,
(i, state) =>
{
result[i] = result[i] + value[i];
});
}
finally
{
cacheLock.ExitWriteLock();
}
return AddOrUpdateStatus.Updated;
}
}
else
{
Add(key, value);
return AddOrUpdateStatus.Added;
}
}
finally
{
cacheLock.ExitUpgradeableReadLock();
}
}
public void Delete(TKey key)
{
cacheLock.EnterWriteLock();
try
{
dictionary.Remove(key);
}
finally
{
cacheLock.ExitWriteLock();
}
}
public enum AddOrUpdateStatus
{
Added,
Updated,
Unchanged
};
}
【问题讨论】:
-
您使用的是较新的 Slim 锁。如果锁定的周期不长,它们会更快,但会消耗更多的 CPU 资源,并且对于更长的锁定可能会更慢。这将是我的第一个猜测。
-
有人可以解释投票否决吗?
标签: c# .net performance dictionary