获取集合中的第一个值然后将其删除的最快方法(大型集合)



我正在构建一个多线程程序来处理大数据,并决定我可以做些什么来调整它。

现在我在普通列表中有 50 000 亿个条目,当我使用多线程时,我使用锁语句。

public string getUsername()
{
string user = null;

lock (UsersToCheckExistList)
{
user = UsersToCheckExistList.First();
UsersToCheckExistList.Remove(user);

}

return user;
}

当我运行较小的列表 500k 行时,它的工作速度要快得多。但是当我加载更大的列表 5-50 磨时,它开始变慢。解决此问题的一种方法是动态创建许多小列表并将它们存储在字典中,这就是我认为我会采用的方式。但是,当我想了解有关优化的更多信息时,我想知道是否有更好的解决方案来完成这项任务?

我想要的只是从集合中获取一个值并同时从集合中删除它。

您使用了错误的工具来完成这项工作 - 显式锁定非常昂贵,更不用说移除List头的成本为 O(Count(。如果你想要一个并发访问的集合,最好在System.Collections.Concurrent中使用类型,因为它们针对并发访问进行了大量优化。从您的用例来看,您似乎想要一个用户队列,因此使用ConcurrentQueue

ConcurrentQueue<string> UsersQueue;
public string getUsername()
{
string user = null;
UsersQueue.TryDequeue(out user);
return user;
}

问题是从列表中删除第一项是 O(n(,因此随着列表的增长,删除第一项需要更长的时间。您可能最好改用队列。由于您需要线程安全,因此可以使用ConcurrentQueue,它为您处理有效的锁定。

您可以将它们全部放入ConcurrentBag(https://learn.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentbag-1?view=netframework-4.8(中,然后每个线程都可以使用TryTake方法抓取一个条目并同时将其删除,然后您无需担心自己进行锁定

如果您有足够的 RAM 用于您的数据,则绝对应该使用 ConcurrentQueue for FIFO 访问您的数据。 但是,如果您没有足够的RAM,则可以尝试使用某些数据库。现代数据库可以非常有效地缓存数据,您将几乎可以立即访问数据并节省操作系统内存免于交换。

最新更新