dotnet / dotnet/runtime

Accessing lazy-allocated collection property just to access its Count to check if it's empty

Open
#120,194 4 comments 0 reactions 0 assignees View on GitHub
area-CodeGen-coreclr tenet-performance
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

I am currently working on some AI-related project, where a `Document` is contains various `DocumentElement` instances. Each of the elements exposes a public property called `Metadata` which is a `Dictionary`:

https://github.com/adamsitnik/dataingestion/blob/d505f5da19da73ce792cbacb813dae4208f1ecc5/src/Microsoft.Extensions.DataIngestion.Abstractions/Document.cs#L92

Then `Document` is split into chunks and they can also have their own metadata:

https://github.com/adamsitnik/dataingestion/blob/d505f5da19da73ce792cbacb813dae4208f1ecc5/src/Microsoft.Extensions.DataIngestion.Abstractions/DocumentChunk.cs#L21

I often have to just check if some metadata was provided or not. In order to do that, I can either access the public property (which is always going to allocate a new dictionary instance) or introduce a new public property that checks only that. I don't like both approaches.

My question to @EgorBo and @AndyAyersMS: would it be possible to recognize such pattern and avoid the allocation?

A benchmark that shows it:

```cs
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

namespace CountCheckPattern
{
internal class Program
{
static void Main(string[] args) => BenchmarkRunner.Run(args: args);
}

[MemoryDiagnoser]
public class PatternBenchmarks
{
[Benchmark]
public bool CountCheck()
{
WithDictionary withDictionary = new();
return withDictionary.Metadata.Count > 0;
}

[Benchmark]
public bool HasMetadataApiCheck()
{
WithDictionary withDictionary = new();
return withDictionary.HasMetadata;
}
}

public struct WithDictionary
{
private Dictionary _metadata;

public Dictionary Metadata => _metadata ??= new();

public bool HasMetadata => _metadata?.Count > 0;
}
}
```

I think it may be quite common pattern. I do recall https://github.com/dotnet/runtime/issues/101922 being reported a while ego by @eerhardt. It would be great if JIT could simply recognize such pattern and optimize it.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.