Materializer optimizations
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
As part of the AOT work (#25009), we now have a (hopefully) 100% faithful C# representation of the materializer expression tree (see code below).
Here are some quick perf fixes we can do:
* [ ] Remove the materializationContext creation when not needed:
```c#
var materializationContext1 = new MaterializationContext(ValueBuffer.Empty, queryContext0.Context);
```
* [ ] Eliminate the object array allocation and the boxing for non-composite key:
```c#
var entry1 = queryContext0.TryGetEntry(key, new object[]{(object)dataReader.GetInt32(0)}, true, out hasNullKey1);
```
* [ ] Avoid unneeded always-true entity type check:
```c#
entityType1 = entityType;
if (entityType1 == entityType)
```
* [ ] Avoid check for null entity type (when is this possible?):
```c#
entry1 = entityType1 == default(IEntityType) ? default(InternalEntityEntry) : queryContext0.StartTracking(entityType1, instance1, shadowValueBuffer1);
```
* [ ] Avoid explicitly setting instance to null, as it's already been initialized to null above:
```c#
else
{
instance1 = null;
}
```
* [ ] #21336
* [ ] #21334
* [ ] Consider the changes here: https://github.com/dotnet/efcore/pull/35128/files#r1846655927
### Code
```c#
IEntityType entityType1;
bool hasNullKey1;
var materializationContext1 = new MaterializationContext(ValueBuffer.Empty, queryContext0.Context);
Blog instance1 = null;
var entry1 = queryContext0.TryGetEntry(key, new object[]{(object)dataReader.GetInt32(0)}, true, out hasNullKey1);
if (!hasNullKey1)
{
if (entry1 != default(InternalEntityEntry))
{
entityType1 = entry1.EntityType;
instance1 = (Blog)entry1.Entity;
}
else
{
var shadowValueBuffer1 = ValueBuffer.Empty;
entityType1 = entityType;
if (entityType1 == entityType)
{
var instance0 = Activator.CreateInstance();
typeof(Blog).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance0, dataReader.GetInt32(0));
typeof(Blog).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance0, dataReader.GetString(1));
instance1 = instance0;
}
else
{
instance1 = null;
}
entry1 = entityType1 == default(IEntityType) ? default(InternalEntityEntry) : queryContext0.StartTracking(entityType1, instance1, shadowValueBuffer1);
}
}
var entity = instance1;
return entity;
```
Contributor guide
Assessment
This issue has not been assessed yet.