最近,我需要选择使用SortedDictionary
和SortedList
,并选择SortedList
。
但是,现在我发现在执行SortedList.Count时我的C#程序正在慢慢爬行,我使用一个被调用数千次的函数/方法来检查。
通常我的程序会在35毫秒内调用该函数10,000次,但在使用SortedList.Count
时,它会减慢到300-400毫秒,基本上慢10倍。
我也试过了SortedList.Keys.Count
,但这又使我的表现再次降低了10倍,超过了3000毫秒。
I have only ~5000 keys/objects in SortedList<DateTime, object_name>
。
我可以通过SortedList[date] (in 35 ms)
轻松地立即从排序列表中检索数据,因此我没有发现列表结构或其持有的对象有任何问题。
这种表现是否正常?
我还可以使用什么来获取列表中的记录数,或者只是检查列表是否已填充? (除了添加一个单独的跟踪标志,我现在可以做)
校正:
对不起,我实际上在使用:
ConcurrentDictionary<string, SortedList<DateTime, string>> dict_list = new ConcurrentDictionary<string, SortedList<DateTime, string>>();
我在不同的地方有各种各样的计数,有时检查列表中的项目和其他时间在ConcurrentDicitonary。所以问题适用于ConcurrentDicitonary,我编写了快速测试代码来确认这一点,这需要350毫秒,而不使用并发。
这是使用ConcurrentDicitonary的测试,显示350毫秒:
public static void CountTest()
{
//Create test ConcurrentDictionary
ConcurrentDictionary<int, string> test_dict = new ConcurrentDictionary<int, string>();
for (int i = 0; i < 50000; i++)
{
test_dict[i] = "ABC";
}
//Access .Count property 10,000 times
int tick_count = Environment.TickCount;
for (int i = 1; i <= 10000; i++)
{
int dict_count = test_dict.Count;
}
Console.WriteLine(string.Format("Time: {0} ms", Environment.TickCount - tick_count));
Console.ReadKey();
}
答案 0 :(得分:3)
答案 1 :(得分:2)
好吧,ConcurrentDictionary<TKey, TValue>
必须同时与多个线程一起正常工作,因此需要一些同步开销。
public int Count
{
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "ConcurrencyCop just doesn't know about these locks")]
get
{
int count = 0;
int acquiredLocks = 0;
try
{
// Acquire all locks
AcquireAllLocks(ref acquiredLocks);
// Compute the count, we allow overflow
for (int i = 0; i < m_tables.m_countPerLock.Length; i++)
{
count += m_tables.m_countPerLock[i];
}
}
finally
{
// Release locks that have been acquired earlier
ReleaseLocks(0, acquiredLocks);
}
return count;
}
}
看起来您需要重构现有代码。由于您没有提供任何代码,我们无法告诉您可以优化的内容。
答案 2 :(得分:0)
对于性能敏感的代码,我不建议使用ConcurrentDictionary.Count
属性,因为它具有锁定实现。您可以使用Interlocked.Increment
代替自己进行计数。