Navigation Menu

Skip to content
This repository has been archived by the owner on Nov 2, 2018. It is now read-only.

Optimize expression compilation memory usage #429

Merged
merged 12 commits into from Jul 13, 2016
Merged

Conversation

pakrym
Copy link
Contributor

@pakrym pakrym commented Jul 12, 2016

Fixes: #425 by caching private field access into local variables.
Also optimizes amount of Monitor.Enter/Exit and try/catch we do for scope services.

Test case:

IdentitySample.Mvc project
Run net451 and request / multiple times to force all services to compile.

Before

234 MB allocation from Microsoft.Extensions.DependencyInjection.ServiceProvider+<>c__DisplayClass17_0.<RealizeService>b__1(), 223 MB because of CAS checks.
And 2700ms total compilation time.
http://i.imgur.com/mm7VunG.png

After

9.8 MB allocation from Microsoft.Extensions.DependencyInjection.ServiceProvider+<>c__DisplayClass17_0.<RealizeService>b__1(), 4.3 MB because of CAS checks.
And 400ms total compilation time.

http://i.imgur.com/pJkQSj5.png

After + No trees for singletons

2.7 MB allocation from Microsoft.Extensions.DependencyInjection.ServiceProvider+<>c__DisplayClass17_0.<RealizeService>b__1(), 1.8 MB because of CAS checks.
And 122ms total compilation time.

http://i.imgur.com/xIep1KC.png

After + No trees for singletons + Short circuit singletons

https://github.com/aspnet/DependencyInjection/pull/429/files#diff-800d14c6aa47e810955d46f860d9502cR52

1.6 MB allocation from Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteExpressionBuilder.Build(IServiceCallSite), 1.2 MB because of CAS checks.
And 89ms total compilation time.

http://i.imgur.com/r3CeDJP.png

@halter73 @davidfowl

@pakrym
Copy link
Contributor Author

pakrym commented Jul 12, 2016

/cc @rynowak

private List<IDisposable> _transientDisposables;

internal ServiceProvider Root { get; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we generally use internal or public on classes that are already internal?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have strong opinion on this, internal property in internal class seems to be pointless now when I look at it.

@halter73
Copy link
Member

@sajayantony Do you still have the application mentioned in aspnet/Hosting#781 that was used in testing the impact of #426?

@halter73
Copy link
Member

I really like the design of this btw @pakrym 👍


namespace Microsoft.Extensions.DependencyInjection.ServiceLookup
{
internal class CallSiteExpressionBuilder: CallSiteVisitor<ParameterExpression, Expression>
Copy link
Member

@davidfowl davidfowl Jul 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: formatting (Space after r in builder)

{
return VisitServiceScopeService(serviceScopeService, argument);
}
throw new NotSupportedException("Call site type is not supported");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the absence of proper pattern matching, let's change this to $"Call sit type '{callSite.GetType()}' is not supported" so we don't have to attach a debugger when we mess up.

@halter73
Copy link
Member

Now I want to know if this makes things faster on coreclr. The smaller trees and avoiding compilation for singletons could be helpful even there.

:shipit:

{
var serviceExpression = VisitCallSite(callSite, ProviderParameter);

List<Expression> body = new List<Expression>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var

@sajayantony
Copy link
Member

@halter73. I've shared the app with you and @pakrym

@pakrym
Copy link
Contributor Author

pakrym commented Jul 13, 2016

Customers app

Before:

http://i.imgur.com/hXrDVoj.png

After

http://i.imgur.com/D8BSRKB.png

@MaherJendoubi
Copy link

@pakrym Which tool are you using?

@halter73
Copy link
Member

halter73 commented Dec 5, 2016

@MaherJendoubi dotMemory

@natemcmaster natemcmaster deleted the pakrym/expression-tree branch November 2, 2018 16:24
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants