Search code examples
c#asynchronoustaskvaluetask

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


I'm doing a benchmark on Task<T> and ValueTask<T>. Source code below:

#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);
    }
}

enter image description here

For the result, the Task<T> is way faster than ValueTask<T>. But why? I really expected the ValueTask<T> would cause less allocation when returning task objects.


Solution

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

    There is a 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 leverage these cached Task for it.

    So, the benchmark result is incorrect because the Task.FromResult is always return cached version of Task object, and the new ValueTask<int>(1) always returns a new value.

    For more information, please read Understanding the Whys, Whats, and Whens of ValueTask.

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