Skip to content
Alan McGovern edited this page Oct 29, 2019 · 2 revisions

Profiling Results

I ran a few tests to show the reduction in memory allocations when using ReusableTask instead of Task. The code snippets and a screenshot of the profiler results are shown below.

Scenario - Basic task

Code:

public async Task RunAsTask ()
{
	async Task Run ()
	{
		await Task.Yield ();
	}
	for (int i = 0; i < 100000; i ++)
		await Run ();
}

Allocations:

Result

Running the code results in about 500,000 object allocations, totalling 13.8MB of memory.

Code:

public async ReusableTask RunAsReusableTask ()
{
	async ReusableTask Run ()
	{
		await Task.Yield ();
	}
	for (int i = 0; i < 100000; i ++)
		await Run ();
}

Allocations:

Result

Running the code results in about 100,000 object allocations, totalling 2.35MB of memory.

Scenario 2 - Basic Task returning a value

Code:

public async Task<int> RunAsTask ()
{
	async Task<int> Run ()
	{
		await Task.Yield ();
		return 5;
	}

	for (int i = 0; i < 100000; i ++)
		await Run ();
	return 100000;
}

Allocations:

Result

Running the code results in about 500,000 object allocations, totalling 13.80MB of memory.

Code:

public async ReusableTask<int> RunAsReusableTask ()
{
	async ReusableTask<int> Run ()
	{
		await Task.Yield ();
		return 5;
	}

	for (int i = 0; i < 100000; i ++)
		await Run ();
	return 100000;
}

Allocations:

Result

Running the code results in about 100,000 object allocations, totalling 2.35MB of memory.

Overall result

Simply changing a method declaration from async Task to async ReusableTask will reduce allocations by about 83%. If these are in a hot path, it may provide a relatively minor performance boost to your application.