为什么 list.Sort((x ,y) => x - y) 在 C# 中没有内存分配

0 c# sorting garbage-collection

C# 源代码: 文本

public void Sort(Comparison<T> comparison) {
    if( comparison == null) {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
    }
    Contract.EndContractBlock();

    if( _size > 0) {
        IComparer<T> comparer = new Array.FunctorComparer<T>(comparison);
        Array.Sort(_items, 0, _size, comparer);
    }
}
Run Code Online (Sandbox Code Playgroud)

这行 IComparer<T> Comparer = new Array.FunctorComparer<T>(comparison); 表明每次对数组进行排序时,都会创建一个新对象。但是当我运行多次时,我发现它根本没有分配。为什么?

这是我的测试代码。

public static void Main(string[] args)
{
    List<int> list = new List<int>();
    list.Add(1);
    list.Add(2);
    for (int i = 0; i < 10; ++i)
    {
        long cnt = GC.GetTotalMemory(false);
        list.Sort((x ,y) => x - y);
        Console.WriteLine(GC.GetTotalMemory(false) - cnt);
    }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*idG 5

目前尚不清楚您使用的是 .NET 6/7 还是 .NET Framework 4.x。但是,List<T>.Sort如果您使用的是 .NET Framework 4.x,该方法会分配内存。

与其直接使用这些GC方法,不如使用专门为执行此类操作而设计的基准测试库。我推荐BenchmarkDotNet。比如一个这样的小程序:

using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;

public static class Program
{
    public static void Main()
    {
        BenchmarkRunner.Run<Benchmarks>();
    }
}

[MemoryDiagnoser] // output memory allocations
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.Net481)]
public class Benchmarks
{
    private readonly List<int> _list = new List<int>() { 1, 2 };

    [Benchmark]
    public void SortList()
    {
        _list.Sort((x, y) => x - y);
    }
}
Run Code Online (Sandbox Code Playgroud)

会给你这样的输出:

方法 工作 运行 意思是 错误 标准差 0代 已分配
排序列表 .NET 7.0 .NET 7.0 7.989纳秒 0.1608纳秒 0.1343纳秒 - -
排序列表 .NET框架4.8.1 .NET框架4.8.1 28.208纳秒 0.5812纳秒 0.9385纳秒 0.0038 24乙

现在您可以看到它确实分配了 0 字节或 24 字节,具体取决于您使用的框架。