背景
我读了一个XML文件,并将一个巨大的(1百万)Person
集合加载到内存中。此集合为IEnumerable(Of Person)
。
Public Class Person
Public Property FirstName As String
Public Property LastName As String
Public Property Age As Int
End Class
我有什么
我想按FirstName
对此集合进行分类,因此我写了这个Linq查询:
Dim groupedCollection = From p
In Persons
Group By p.FirstName
Into PersonsWithSameName = Group
现在我想将此groupedCollection
转换为Dictionary
。所以我写这个:
Dim myPersonDictionary = groupedCollection.ToDictionary(Function(x) x.FirstName,
Function(x) x.PersonsWithSameName)
问题
问题在于.ToDictionary
功能的表现对于这么大的收藏来说是可怕的。我不确定,但我认为这是因为它首先列举了我的原始集合,因为我将所有集合从开头到结尾都保留为IEnumerable
,除了我需要枚举的情况。
我已阅读here,将Group By
和.ToDictionary
放在一起并不是一个好主意。但是,当我使用建议的appraoch时,我看不出有什么区别(因此,首先在我的Select
上执行groupedCollection
)。
我想要实现的内容是Dictionary(Of String, IEnumerable(Of Person))
(或者我可以以类似方式使用的其他数据结构)。
我的问题是,我如何以更好的方式(在效果方面)获得此Dictionary
。
答案 0 :(得分:0)
加载XML时很可能出现问题。
这是一个显示原因的例子:
var rnd = new Random();
Func<string> createName =
() => new string(
Enumerable
.Range(0, 3)
.Select(n => (char)(rnd.Next(0, 26) + 'a'))
.ToArray());
var sw = Stopwatch.StartNew();
var persons =
Enumerable
.Range(0, 1000000)
.Select(x => new { FirstName = createName(), LastName = createName() })
.ToArray();
var el1 = sw.Elapsed;
var grouped = persons.GroupBy(p => p.FirstName, p => p.LastName).ToArray();
var el2 = sw.Elapsed;
var dictionary = grouped.ToDictionary(p => p.Key, p => p);
var el3 = sw.Elapsed;
Console.WriteLine(el1.TotalMilliseconds);
Console.WriteLine(el2.Subtract(el1).TotalMilliseconds);
Console.WriteLine(el3.Subtract(el2).TotalMilliseconds);
当我运行此代码时,我得到一个这样的输出:
1095.7095 266.2265 1.624
所以它需要1095.7095毫秒才能创建对象。然后需要266.2265将它们按名字分组。最后创建字典只需要1.624毫秒。
如果您遇到性能问题,那么它不在分组或创建字典中。否则,您需要发布您的代码并告诉我们您如何确定问题所在。