Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么列表<>;。OrderBy LINQ比IComparable快+;列表<>;。在调试模式下排序?_C#_Linq_Sorting_Benchmarking - Fatal编程技术网

C# 为什么列表<>;。OrderBy LINQ比IComparable快+;列表<>;。在调试模式下排序?

C# 为什么列表<>;。OrderBy LINQ比IComparable快+;列表<>;。在调试模式下排序?,c#,linq,sorting,benchmarking,C#,Linq,Sorting,Benchmarking,我感兴趣的是,使用LINQ还是通过实现IComparable接口和List.sort对类进行排序会更快。当LINQ代码更快时,我非常惊讶 为了进行测试,我创建了一个非常简单的类,使用不太合适的名称TestSort,实现了IComparable class TestSort: IComparable<TestSort> { private int age; private string givenName; public int Age {

我感兴趣的是,使用LINQ还是通过实现IComparable接口和List.sort对类进行排序会更快。当LINQ代码更快时,我非常惊讶

为了进行测试,我创建了一个非常简单的类,使用不太合适的名称TestSort,实现了IComparable

class TestSort: IComparable<TestSort>  {
    private int age;
    private string givenName;

    public int Age {
        get {
            return age;
        }
        set {
            age = value;
        }
    }

    public string GivenName {
        get {
            return givenName;
        }
        set {
            givenName = value;
        }
    }

    public TestSort(int age, string name) {
        this.age = age;
        this.givenName = name;
    }

    public int CompareTo(TestSort other) {
        return this.age.CompareTo(other.age);
    }
}

但是我仍然很想知道为什么IComparable在调试模式下速度较慢。

如果在开始测量之前确保所有内容都是JIT的,那么可能会得到不同的结果(我还建议使用
秒表
类来测量时间):


根据我的测量(添加上述代码后),IComparable总是更快(即使在调试中)。

这可能是调用方法
CompareTo
的开销,当编译并在发布模式下运行时,该方法将被内联替换。

排序使用未优化的快速排序,在最坏的情况下,它的复杂性是n*n。我不知道orderby使用了什么,但我知道它没有使用相同的方法,因为它是一种稳定的排序,不像
数组。sort

对于我来说,我将使用Linq和IComparable(当这是最常用或唯一的排序方法时)。在本例中,项是一个
TestSort:IComparable

ll
可以是任何IEnumerable:列表、数组等

此外,在
compare to
中,您可以使用多种方式来比较。。。例如,您可以执行以下操作:

  public int CompareTo(TestSort other) {
        return this.age != other.age ? this.age.CompareTo(other.age) : this.dateOfBirth.CompareTo(other.dateOfBirth);
    }

您是否尝试过在调试模式(项目属性)下设置优化,并查看其是否仍然较慢?如果没有,那就可以解释了。优化代码已打开。。。我在寻找一个实际的原因,而不是一个促成因素。我不是想解决这个问题,这两种方法对于我来说都足够快了,我只是想知道为什么。你如何确保在测量之前事情都是JIT的?还有。在我的电脑上进行大约900次测试,IComparable速度更快。但如果循环次数超过1000次,LINQ会变得更快。因此,初始LINQ设置会有一些开销,但重复使用最终会更快。在代码段中,当您调用
ll.OrderBy()
时,列表已在前一行排序,因此调用
OrderBy()
时,可能需要进行的计算更少。您能否验证在秒表测试中,您没有对已排序的列表调用
OrderBy()
?@lorddev此代码仅用于JIT方法,因此实际测量将更加准确。然而,现在最好只使用.Linq to objects OrderBy使用稳定的快速排序,而不是使用不稳定的快速排序的Array.Sort。算法的速度代价应该没有太大的差别。它们都是O(n logn)。您知道它是优化的还是仍然是相同的n^2最坏情况吗?
IComparable<T>:
2965.1696

LINQ:
2181.1248
IComparable<T>:
1593.0911

Linq:
1958.1119
var ll = ts2.ToList();
ll.Sort();
ll.OrderBy(item => item.Age).ToList();
var sorted = ll.OrderBy(item => item); // This automatically used age to compare, as it's defined in CompareTo
  public int CompareTo(TestSort other) {
        return this.age != other.age ? this.age.CompareTo(other.age) : this.dateOfBirth.CompareTo(other.dateOfBirth);
    }