{"action":"created","issue":{"url":"https://api.github.com/repos/Microsoft/visualfsharp/issues/4465","repository_url":"https://api.github.com/repos/Microsoft/visualfsharp","labels_url":"https://api.github.com/repos/Microsoft/visualfsharp/issues/4465/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/visualfsharp/issues/4465/comments","events_url":"https://api.github.com/repos/Microsoft/visualfsharp/issues/4465/events","html_url":"https://github.com/Microsoft/visualfsharp/pull/4465","id":303298217,"number":4465,"title":"Make ErrorStrings properties instead of evaluating them in cctor","user":{"login":"vbfox","id":131878,"avatar_url":"https://avatars0.githubusercontent.com/u/131878?v=4","gravatar_id":"","url":"https://api.github.com/users/vbfox","html_url":"https://github.com/vbfox","followers_url":"https://api.github.com/users/vbfox/followers","following_url":"https://api.github.com/users/vbfox/following{/other_user}","gists_url":"https://api.github.com/users/vbfox/gists{/gist_id}","starred_url":"https://api.github.com/users/vbfox/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vbfox/subscriptions","organizations_url":"https://api.github.com/users/vbfox/orgs","repos_url":"https://api.github.com/users/vbfox/repos","events_url":"https://api.github.com/users/vbfox/events{/privacy}","received_events_url":"https://api.github.com/users/vbfox/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":20,"created_at":"2018-03-07T23:25:06Z","updated_at":"2018-03-09T15:03:51Z","closed_at":null,"author_association":"NONE","pull_request":{"url":"https://api.github.com/repos/Microsoft/visualfsharp/pulls/4465","html_url":"https://github.com/Microsoft/visualfsharp/pull/4465","diff_url":"https://github.com/Microsoft/visualfsharp/pull/4465.diff","patch_url":"https://github.com/Microsoft/visualfsharp/pull/4465.patch"},"body":"While investigating the `Argu` performance problem described in https://github.com/fsprojects/Argu/pull/105 one of the things that was hard to optimize away was that `fsharp.core!<StartupCode$FSharp-Core>.$Prim-types..cctor()` is taking between 30 and 70ms to load satellite assemblies as soon as an F# application uses some specific parts of F# core (`Seq.distinct` in Argu case) and the reason is that LanguagePrimitives.ErrorStrings are static properties defined as let members and so they are present in the static constructor generated for the `Prim-types` file.\r\n\r\nWhile a few dozen milliseconds aren't a problem for big applications, during startup for command lines applications that might run in hundreds of milliseconds it's a big part of their runtime. It's also one of the only case I could find where the strings are resolved in the static constructor, all other calls to SR.GetString are done directly without any caching.\r\n\r\nThe consequence for speed on a simple Argu usage can be seen here in the top left (`OTHER <<mscorlib.ni!S` is  `OTHER <<mscorlib.ni!System.Resources.ResourceManager.GetString(...)>>`) :\r\n\r\n![flame graph](https://user-images.githubusercontent.com/131878/37056147-d2c60794-2183-11e8-8c36-4a2d9d1ff834.png)\r\n\r\n* As the members are part of the public signature of FSharp.Core I kept the same signature (The surface area files haven't been touched).\r\n* Regarding the behavior it should be the same except that the culture used for the error messages will be the current one at the time of the call instead of whatever was the current culture when the static constructor was called (But it sounds like a bugfix to me 😉)"},"comment":{"url":"https://api.github.com/repos/Microsoft/visualfsharp/issues/comments/371837719","html_url":"https://github.com/Microsoft/visualfsharp/pull/4465#issuecomment-371837719","issue_url":"https://api.github.com/repos/Microsoft/visualfsharp/issues/4465","id":371837719,"user":{"login":"vbfox","id":131878,"avatar_url":"https://avatars0.githubusercontent.com/u/131878?v=4","gravatar_id":"","url":"https://api.github.com/users/vbfox","html_url":"https://github.com/vbfox","followers_url":"https://api.github.com/users/vbfox/followers","following_url":"https://api.github.com/users/vbfox/following{/other_user}","gists_url":"https://api.github.com/users/vbfox/gists{/gist_id}","starred_url":"https://api.github.com/users/vbfox/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vbfox/subscriptions","organizations_url":"https://api.github.com/users/vbfox/orgs","repos_url":"https://api.github.com/users/vbfox/repos","events_url":"https://api.github.com/users/vbfox/events{/privacy}","received_events_url":"https://api.github.com/users/vbfox/received_events","type":"User","site_admin":false},"created_at":"2018-03-09T15:03:51Z","updated_at":"2018-03-09T15:03:51Z","author_association":"NONE","body":"I'm open to suggestions :)\r\n\r\nBut I don't want to end in the \"Too complex so we're slow forever because compat\" slot.\r\n\r\nOther solutions I see are :\r\n* Fake the metadata somehow so that the static-property version looks like the val version\r\n* Write the module & it's metadata entirely in IL (is it possible ?)\r\n* Change the compiler so that cctor are generated per-file-per-module instead of per-file (With the bonus that it might solve this kind of problems in other places too)\r\n* Rewrite the IL after the build to remove the cctor parts and replace the properties."}}
{"actor":{"display_login":"vbfox"}}