{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/corefx/issues/13561","repository_url":"https://api.github.com/repos/dotnet/corefx","labels_url":"https://api.github.com/repos/dotnet/corefx/issues/13561/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/13561/comments","events_url":"https://api.github.com/repos/dotnet/corefx/issues/13561/events","html_url":"https://github.com/dotnet/corefx/pull/13561","id":188624330,"number":13561,"title":"Use cached reflection for Queryable methods","user":{"login":"bartdesmet","id":7324746,"avatar_url":"https://avatars.githubusercontent.com/u/7324746?v=3","gravatar_id":"","url":"https://api.github.com/users/bartdesmet","html_url":"https://github.com/bartdesmet","followers_url":"https://api.github.com/users/bartdesmet/followers","following_url":"https://api.github.com/users/bartdesmet/following{/other_user}","gists_url":"https://api.github.com/users/bartdesmet/gists{/gist_id}","starred_url":"https://api.github.com/users/bartdesmet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bartdesmet/subscriptions","organizations_url":"https://api.github.com/users/bartdesmet/orgs","repos_url":"https://api.github.com/users/bartdesmet/repos","events_url":"https://api.github.com/users/bartdesmet/events{/privacy}","received_events_url":"https://api.github.com/users/bartdesmet/received_events","type":"User","site_admin":false},"labels":[{"id":197706871,"url":"https://api.github.com/repos/dotnet/corefx/labels/cla-already-signed","name":"cla-already-signed","color":"009800","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2016-11-10T21:34:11Z","updated_at":"2016-11-10T23:46:30Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/13561","html_url":"https://github.com/dotnet/corefx/pull/13561","diff_url":"https://github.com/dotnet/corefx/pull/13561.diff","patch_url":"https://github.com/dotnet/corefx/pull/13561.patch"},"body":"Generated `CachedReflectionInfo` to cache `MethodInfo` objects representing `Queryable` methods for use by these methods to construct expression trees.\r\n\r\nPrior to .NET Core, the construction of expression trees was using `MethodBase.GetCurrentMethod` to obtain the open generic method representing the containing method whose call's expression representation was being built.\r\n\r\nAt some point, `GetCurrentMethod` was substituted for an `infoof` based approach using an expression tree to obtain the `MethodInfo` (see removed code in this PR). This causes allocation of an expression tree (with a ton of runtime checks) for every call to a `Queryable` method only to get the `MethodInfo` instance to use in the resulting expression tree. All we really need is a `ldftn` instruction.\r\n\r\nThis PR replaces this approach by introducing a `CachedReflectionInfo` class containing static properties and methods to obtain (closed generic) `MethodInfo` instances for the `Queryable` methods. The (open generic) `MethodInfo` instances are cached in static fields. This is very similar to the technique we use in `System.Linq.Expressions` to cache reflection objects. The means to obtain the `MethodInfo` is using a method group conversion to a `Delegate` and a call to `GetMethodInfo` (instead of being expression based).\r\n\r\nThe `CachedReflectionInfo` type was generated using a T4 template. We could check that in if we want, but we don't have an precedent for doing that AFAIK.\r\n\r\nCC @JonHanna, @stephentoub"},"comment":{"url":"https://api.github.com/repos/dotnet/corefx/issues/comments/259841783","html_url":"https://github.com/dotnet/corefx/pull/13561#issuecomment-259841783","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/13561","id":259841783,"user":{"login":"stephentoub","id":2642209,"avatar_url":"https://avatars.githubusercontent.com/u/2642209?v=3","gravatar_id":"","url":"https://api.github.com/users/stephentoub","html_url":"https://github.com/stephentoub","followers_url":"https://api.github.com/users/stephentoub/followers","following_url":"https://api.github.com/users/stephentoub/following{/other_user}","gists_url":"https://api.github.com/users/stephentoub/gists{/gist_id}","starred_url":"https://api.github.com/users/stephentoub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stephentoub/subscriptions","organizations_url":"https://api.github.com/users/stephentoub/orgs","repos_url":"https://api.github.com/users/stephentoub/repos","events_url":"https://api.github.com/users/stephentoub/events{/privacy}","received_events_url":"https://api.github.com/users/stephentoub/received_events","type":"User","site_admin":false},"created_at":"2016-11-10T23:46:30Z","updated_at":"2016-11-10T23:46:30Z","body":"> Maybe it's coming back? \r\n\r\nAlready did (for 1.2):\r\nhttps://github.com/dotnet/corefx/blob/bffef76f6af208e2042a2f27bc081ee908bb390b/src/System.Runtime/ref/System.Runtime.cs#L4793"}}
{"actor":{"display_login":"stephentoub"}}