为什么 Task<T> 比 ValueTask<T> 快?

Why is Task<T> faster than ValueTask<T>?

我正在 Task<T> and ValueTask<T> 上进行基准测试。源代码如下:

#LINQPad optimize+     // Enable compiler optimizations

void Main()
{
    Util.AutoScrollResults = true;
    BenchmarkRunner.Run<TaskAndValueTaskComparsion>();
}

[ShortRunJob]
public class TaskAndValueTaskComparsion
{
    [Benchmark]
    public ValueTask<int> RunValueTaskWithNew()
    {
        return new ValueTask<int>(1);
    }
    
    [Benchmark]
    public Task<int> RunTaskFromResult()
    {
        return Task.FromResult(1);
    }
}

对于结果,Task<T>ValueTask<T> 快得多。但为什么?我真的希望 ValueTask<T> 在返回任务对象时会导致更少的分配。

Thanks for all the commenters. Let's summarize all these valuable info.

有一个TaskCache.cs in the .NET runtime that create cacheable Task for various primitive type's value such as true(bool), false(bool), -1 ~ 9(int). The Task.FromResult利用这些缓存的任务。

因此,基准测试结果不正确,因为 Task.FromResult 始终是 return Task 对象的缓存版本,而 new ValueTask<int>(1) 始终是 return 的新值。

更多信息,请阅读Understanding the Whys, Whats, and Whens of ValueTask

If you can read Chinese, I also wrote a post yesterday. See here.