Linq性能用于内存中的收集

我有一个列表:集合用户有大约100K +用户记录(所有用户对象从数据库中完全加载,包括Bio,名字,姓氏等字段)。 此应用程序从应用程序启动时从数据库中获取并保存在内存中。

然后我有以下代码:

User cachedUser = users.FirstOrDefault(x => string.Equals(x.UserName, username, StringComparison.CurrentCultureIgnoreCase)); 

我用它来从这个集合中获取用户。 但不知何故,我注意到这个操作非常慢。 使用Linq查询大型对象的内存集合时是否存在性能问题? 我是否应该在每次想要获得用户时调用数据库?

如果要优化响应时间,可以创建Dictionary并在以下位置搜索用户:

  Dictionary usersDictionary = new (StringComparer.CurrentCultureIgnoreCase); // After querying the users from the DB add them to the dictionary usersDictionary.Add(user.UserName, user); // Then when you need to retrieve a user User retrieveUser = null; usersDictionary.TryGetValue(username, out retrieveUser); 

希望有所帮助!

我想您可能需要根据您提供给我们的信息重新考虑您的架构。 利用数据库,让它为您完成搜索工作。 之后观察,测量并做出相应的更改。 你可能会意识到你过早优化了整个事情。

您的LINQ查询与任何其他迭代技术(循环,数组中的搜索)一样,将访问每个记录,直到找到所请求的记录。 在最坏的情况下,这意味着100k比较。 为了加快速度,您有以下选择:

  1. 使用排序列表或字典:二进制搜索要快得多。 使用ORDER BY从数据库中获取数据时对数据进行排序
  2. 使用DataSet。 它就像一个内存数据库,提供更快的搜索
  3. 将数据保留在数据库中并设置适当的索引以便更快地访问

我建议使用数据库,原因如下:

  • 存储100k记录是浪费内存,您可能永远不会使用它们
  • 一旦更改数据,就必须刷新缓存,这可能相当复杂
  • Web应用程序是multithreading的(每个请求都在自己的线程中运行)。 如果您更改数据,则必须与锁同步。
  • 数据库可以缓存频繁调用的数据
  • 你必须编写更少的代码
  • 你有一个无状态的Web应用程序,可以更好地扩展(Web场)
  • 您的应用程序可能有其他数据,您无法将所有内容存储在内存中

您注意到的搜索性能不同是因为数据库使用索引来定位数据库中的字符串,但您在内存中只需搜索所有记录,直到找到该记录。 此外,数据库保留字符串的哈希值,并搜索更快的数字哈希,而不是实际字符串比较。

Dictionary<>也是一个索引,但是有一个延迟添加数据,当数据开始增长时,因为当它添加一些数据时,每次都搜索将它放在正确的索引点的位置。

此外,数据库缓存结果,许多数据库缓存也进行索引并创建额外的统计信息,以帮助快速定位您要查找的内容。

最好让数据库进行搜索,除非你能为更多的自定义案例做更快的事情。