RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 780178
Accepted
Adam Shakhabov
Adam Shakhabov
Asked:2020-02-05 00:56:07 +0000 UTC2020-02-05 00:56:07 +0000 UTC 2020-02-05 00:56:07 +0000 UTC

IOrderedEnumerable<T> 与 SortedSet<T>:哪个序列化更快?

  • 772

进行测量以找出哪个集合创建和迭代更快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 中序列化所有这些优点,这会更快地发生吗?

我不够聪明,无法测量这两个对象的序列化速度,如果将这样的测量显示为答案,我将不胜感激。

c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Pavel Mayorov
    2020-02-05T14:38:34Z2020-02-05T14:38:34Z

    你的第一个错误是你使用了一百万个相同元素的列表。而且SortedSet 不存储相同的元素,也就是说,您实际上只有一个元素存储在SortedSet 中。

    如果你让所有元素都不同(Name = "Name" + i) - 那么 SortedSet 的运行时间将增加 10 倍。

    您的第二个错误是您在不同的方法中使用了不同的字符串比较算法!

    您的 SortedSet 使用最快的算法StringComparison.Ordinal来比较字符数 - 而您的 GroupBy 使用慢速算法StringComparison.CurrentCulture(例如,在排序时考虑字母“e”和字母“e”的两种形式的相等性)。

    只需告诉 OrderBy 使用快速字符串比较 ( .OrderBy(u => u.FullName, StringComparer.Ordinal);) 即可显着加快排序速度。

    结果,我得到了这样的图片:

    排序集:1214ms

    IOrderedEnumerable:920 毫秒

    换句话说,结果证明使用 OrderBy 更快,因为它应该是:平衡二叉树是一个相当重的数据结构,并且对数组进行简单排序,在所有其他条件相同的情况下,总是比树快(如果,当然,排序一次就足以完成您的任务)。


    使用 OrderBy 在序列化之前准备数据。不应该使用 SortedSet,因为它解决了一个完全不同的问题。

    如果您需要不惜一切代价加速 - 您可以使用List<T>.Sort它,它会更快一点。

    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5