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

[Perf] HttpContextFactory should only wrap ReadOnly feature collections #310

Closed
Tratcher opened this issue Jul 28, 2015 · 10 comments
Closed
Assignees
Milestone

Comments

@Tratcher
Copy link
Member

https://github.com/aspnet/Hosting/blob/dev/src/Microsoft.AspNet.Hosting/Builder/HttpContextFactory.cs#L14

IFeatureCollections can be marked as IsReadOnly or not. HttpContextFactory currently assumes they are all read only and wraps them in a mutable FeatureCollection. This has some perf overhead where it creates extra Dictionaries, etc, and is redundant if the server already provided a mutable collection.

Recommendation: Only wrap the given feature collection if is marked as IsReadOnly.

@Tratcher Tratcher added the bug label Jul 28, 2015
@Tratcher Tratcher self-assigned this Jul 28, 2015
@glennc glennc added this to the 1.0.0-beta8 milestone Aug 5, 2015
@davidfowl davidfowl added Perf and removed bug labels Aug 15, 2015
@Tratcher
Copy link
Member Author

Nevermind, FeatureCollection has made significant improvements in this scenario.

@Tratcher Tratcher removed the wontfix label Oct 4, 2015
@Tratcher
Copy link
Member Author

Tratcher commented Oct 4, 2015

@lodejard @benaadams

@Tratcher Tratcher reopened this Oct 4, 2015
@Tratcher Tratcher removed this from the 1.0.0-beta8 milestone Oct 4, 2015
@benaadams
Copy link
Contributor

I did have a look at FeatureCollection when checking the codebase and in isolation its pretty efficient at what it does; so couldn't come up with any improvements.

Taking a step back there are FeatureCollection improvements coming in Kestrel; which regardless of metrics, have the distinct allocation advantage of already being created, and this wrapping would prevent it being utilised passed the point the context is created.

However, I don't have the holistic view on what circumstances; if any, IFeatureCollection could be readonly, and whether FeatureCollection is needed at all; but if it is, you could make the one line change from:

return new DefaultHttpContext(new FeatureCollection(featureCollection));

to what @Tratcher originally suggested (in preferred line break formatting)

return new DefaultHttpContext(
    featureCollection.IsReadOnly 
    ? new FeatureCollection(featureCollection) 
    : featureCollection);

which would work and allow the changes in Kestrel's collection to flow through. So that would be an easy fix?

Then open question on when would the IFeatureCollection be readonly? Bearing in mind throwing NotImplementedExecption at runtime is a pretty terrible thing.

@Tratcher
Copy link
Member Author

Tratcher commented Oct 4, 2015

Allowing the IFeatureCollection to be read-only can make for simpler server implementations. FeatureCollection makes up the difference.

Or we cut that and just ask the simple servers to use FeatureCollection directly.

@benaadams
Copy link
Contributor

FeatureCollection is a very interesting collection; especially when you consider you can pass an FeatureCollection to its constructor; boom you've got javascript's prototype inheritance right there; change the original and it flows through if its not overridden at some stage. I digress...

Allowing the IFeatureCollection to be read-only can make for simpler server implementations.

Are there any existing implementations? Doing an if check/ternary operator here is about as lightweight as you can get, so if you want to support that scenario I don't think there is any disadvantage.

If there aren't any existing implementations, pushing out the readonly might make sense as its sort of a hidden intent coercion (e.g. "I made this readonly; with NotImplementedExecptions why can you change it and get no errors?")

So is definitely a design call.

Though I'd favour changing it to wrap conditionally, this instant as you've suggested; as it would be more performant and otherwise will cause issues with Kestrel's new implementation - then pick up readonly in an internal discussion? (even if its only 5 secs 😝)

However... as I said at the start; the FeatureCollection is pretty lightweight and has very interesting properties, and might work well for routing? Particularly aspnet/Routing#211: Optimize allocations in RouteData + Optimize the design of attribute routing where you could have default route paths per segment in a tree, that then are overridden and overridden again by attributes on the specifics; yet maintain their default routing where not overridden?

@benaadams
Copy link
Contributor

In fact just made a PR for it...

@davidfowl
Copy link
Member

I think we should keep IFeatureCollection and do the optimization.

@davidfowl davidfowl added this to the 1.0.0-rc1 milestone Oct 4, 2015
@benaadams
Copy link
Contributor

@davidfowl wasn't suggesting removing IFeatureCollection as a possibility, just ReadOnly. Though the optimization gives you 99.999% of the benefits; so probably isn't worth interface churn.

@Tratcher
Copy link
Member Author

Tratcher commented Oct 5, 2015

@davidfowl
Copy link
Member

Yes, we can just make that part of the contract.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants