进行测量以找出哪个集合创建和迭代更快IOrderedEnumerable<T>或SortedSet<T>
internal class User
{
public string Surname { get; set; }
public string Name { get; set; }
public int DocumNumber { get; set; }
}
internal class UserDto : IComparable<UserDto>
{
public string FullName { get; set; }
public int DocumNumber { get; set; }
public int CompareTo(UserDto other)
{
return string.Compare(this.FullName, other.FullName, StringComparison.Ordinal);
}
}
class Program
{
static void Main(string[] args)
{
const int count = 1000000;
var users = new List<User>();
for (var i = 0; i < count; i++)
{
users.Add(new User
{
Name = "Name",
Surname = "Surname",
DocumNumber = i
});
}
// IOrderedEnumerable<T>
var watch = Stopwatch.StartNew();
var userDtoList = new List<UserDto>();
foreach (var user in users)
{
userDtoList.Add(new UserDto
{
FullName = $"{user.Surname} {user.Name}",
DocumNumber = user.DocumNumber
});
}
var orderedEnumerableUserDto = userDtoList.OrderBy(u => u.FullName);
foreach (var userDto in orderedEnumerableUserDto)
{
// просто делаем некую работу
}
watch.Stop();
Console.WriteLine("IOrderedEnumerable<T>: {0}ms", watch.ElapsedMilliseconds);
// SortedSet<T>
watch.Restart();
var sortedSetUserDto = new SortedSet<UserDto>();
foreach (var user in users)
{
sortedSetUserDto.Add(new UserDto
{
FullName = $"{user.Surname} {user.Name}",
DocumNumber = user.DocumNumber
});
}
foreach (var userDto in sortedSetUserDto)
{
// просто делаем некую работу
}
watch.Stop();
Console.WriteLine("SortedSet<T>: {0}ms", watch.ElapsedMilliseconds);
System.Console.ReadKey();
}
}
根据三个测量的结果,平均值如下:
IOrderedEnumerable<T>: 4661 ms
SortedSet<T>: 611 ms
快了近 8 倍SortedSet<T>。
一点关于 IOrderedEnumerable
在帖子的开头,我称它为IOrderedEnumerable<T>集合。我知道我错了,对不起,我只是不知道在比较集合和界面时如何正确操作。
我不明白这个接口是如何工作的,它返回什么样的枚举器。因为如果我们从两个测量中删除块
foreach (var userDto in orderedEnumerableUserDto)
{
// просто делаем некую работу
}
我们将看到测量显示相同的结果。我确定表达式
var orderedEnumerableUserDto = userDtoList.OrderBy(u => u.FullName);
不会在内存中进行任何排序,否则会花费很多时间。在那里,很可能只发生了对象的标记——枚举器接口将调用哪个队列中的谁IOrderedEnumerable,例如
问题
我提出了我的想法IOrderedEnumerable<T>,因为我想说如果我从内部理解它是如何工作的,那么也许这个问题就不会出现。好吧,问题是:这两个选项中的哪一个更好地返回给控制器,这将在 JSON 中序列化所有这些优点,这会更快地发生吗?
我不够聪明,无法测量这两个对象的序列化速度,如果将这样的测量显示为答案,我将不胜感激。

你的第一个错误是你使用了一百万个相同元素的列表。而且SortedSet 不存储相同的元素,也就是说,您实际上只有一个元素存储在SortedSet 中。
如果你让所有元素都不同(
Name = "Name" + i) - 那么 SortedSet 的运行时间将增加 10 倍。您的第二个错误是您在不同的方法中使用了不同的字符串比较算法!
您的 SortedSet 使用最快的算法
StringComparison.Ordinal来比较字符数 - 而您的 GroupBy 使用慢速算法StringComparison.CurrentCulture(例如,在排序时考虑字母“e”和字母“e”的两种形式的相等性)。只需告诉 OrderBy 使用快速字符串比较 (
.OrderBy(u => u.FullName, StringComparer.Ordinal);) 即可显着加快排序速度。结果,我得到了这样的图片:
换句话说,结果证明使用 OrderBy 更快,因为它应该是:平衡二叉树是一个相当重的数据结构,并且对数组进行简单排序,在所有其他条件相同的情况下,总是比树快(如果,当然,排序一次就足以完成您的任务)。
使用 OrderBy 在序列化之前准备数据。不应该使用 SortedSet,因为它解决了一个完全不同的问题。
如果您需要不惜一切代价加速 - 您可以使用
List<T>.Sort它,它会更快一点。