{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/coreclr/pulls/comments/41805130","id":41805130,"diff_hunk":"@@ -36,9 +36,35 @@ private unsafe string ChangeCase(string s, bool toUpper)\n             }\n \n             string result = string.FastAllocateString(s.Length);\n-            fixed (char* pBuf = result)\n+\n+            fixed (char* pResult = result)\n             {\n-                Interop.GlobalizationInterop.ChangeCase(s, s.Length, pBuf, result.Length, toUpper, m_needsTurkishCasing);\n+                if (IsAsciiCasingSameAsInvariant && s.IsAscii())","path":"src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs","position":9,"original_position":9,"commit_id":"d9eab01362d379cd58fdd38498413cb914ba260e","original_commit_id":"d9eab01362d379cd58fdd38498413cb914ba260e","user":{"login":"ellismg","id":9602953,"avatar_url":"https://avatars.githubusercontent.com/u/9602953?v=3","gravatar_id":"","url":"https://api.github.com/users/ellismg","html_url":"https://github.com/ellismg","followers_url":"https://api.github.com/users/ellismg/followers","following_url":"https://api.github.com/users/ellismg/following{/other_user}","gists_url":"https://api.github.com/users/ellismg/gists{/gist_id}","starred_url":"https://api.github.com/users/ellismg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ellismg/subscriptions","organizations_url":"https://api.github.com/users/ellismg/orgs","repos_url":"https://api.github.com/users/ellismg/repos","events_url":"https://api.github.com/users/ellismg/events{/privacy}","received_events_url":"https://api.github.com/users/ellismg/received_events","type":"User","site_admin":false},"body":"I would rather do it this way, IsAsciiCasingSameAsInvariant should be cached per TextInfo, which are not created frequently.  Strings are, and I would rather us save the walk of the string if it going to be worthless.  Just my two cents.","created_at":"2015-10-12T21:49:03Z","updated_at":"2015-10-12T21:49:03Z","html_url":"https://github.com/dotnet/coreclr/pull/1747#discussion_r41805130","pull_request_url":"https://api.github.com/repos/dotnet/coreclr/pulls/1747","_links":{"self":{"href":"https://api.github.com/repos/dotnet/coreclr/pulls/comments/41805130"},"html":{"href":"https://github.com/dotnet/coreclr/pull/1747#discussion_r41805130"},"pull_request":{"href":"https://api.github.com/repos/dotnet/coreclr/pulls/1747"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/coreclr/pulls/1747","id":47455802,"html_url":"https://github.com/dotnet/coreclr/pull/1747","diff_url":"https://github.com/dotnet/coreclr/pull/1747.diff","patch_url":"https://github.com/dotnet/coreclr/pull/1747.patch","issue_url":"https://api.github.com/repos/dotnet/coreclr/issues/1747","number":1747,"state":"open","locked":false,"title":"[WIP] Add ASCII optimization to string.ToLower/ToUpper on Unix","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},"body":"I've marked this [WIP] as I'm not sure yet whether we want to do something like this.\r\n\r\nThe commit adds a \"fast path\" to string.ToLower/ToUpper for ASCII on Unix, where it appears that ICU's support for changing case is notably slower than our Windows implementation.  It's possible there are additional optimizations that could be done around how we use ICU; this commit takes the approach of skipping ICU for the known case where we can easily process the casing in C#.\r\n\r\nHere are results of a test on my Windows host and Linux VM, before and after the change.  IsAscii is implemented in the runtime to cache a bit on String, so the test look at both a string that's reused across all of the calls vs allocating a new string each time.  The ASCII tests use a repeated ASCII character whereas the Unicode tests use a repeated non-ASCII UTF16 character.\r\n\r\n|Name|Windows Host|Linux VM Before|Linux VM After|Improvement %|\r\n|---|---|---|---|---|\r\n|Existing string, 1 ASCII char|1.5020384|2.5553898|1.842431|27.9%|\r\n|New string, 1 ASCII char|1.5795358|4.1745525|3.3188007|20.5%|\r\n|Existing string, 100 ASCII char|4.8845411|17.6219381|8.2425335|53.2%|\r\n|New string, 100 ASCII char|5.453854|18.9850037|11.4704103|39.5%|\r\n|Existing string, 1 Uni char|1.4366129|2.5397759|2.6457702|-4.1%|\r\n|New string, 1 Uni char|1.5677327|4.0675378|4.297064|-5.6%|\r\n|Existing string, 100 Uni char|1.4341564|2.6690188|2.559565|4.1%|\r\n|New string, 100 Uni char|5.5340518|17.3497491|17.993312|-3.7%|\r\n\r\nNote that these numbers fluctuate a bit from run to run, so some of the smaller percentages border on noise, but at a high level, ASCII cases gain significantly from the change while cases with non-ASCII characters suffer a bit.\r\n\r\nThoughts?\r\n\r\ncc: @jkotas, @ellismg, @steveharter, @tarekgh, @eerhardt \r\nRelated to https://github.com/dotnet/corefx/issues/3574","created_at":"2015-10-12T19:30:58Z","updated_at":"2015-10-12T21:49:03Z","closed_at":null,"merged_at":null,"merge_commit_sha":"64bc1f21bdd666765a9de9cb4d471b434fbdb53a","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/coreclr/pulls/1747/commits","review_comments_url":"https://api.github.com/repos/dotnet/coreclr/pulls/1747/comments","review_comment_url":"https://api.github.com/repos/dotnet/coreclr/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/coreclr/issues/1747/comments","statuses_url":"https://api.github.com/repos/dotnet/coreclr/statuses/d9eab01362d379cd58fdd38498413cb914ba260e","head":{"label":"stephentoub:string_tolowerupper_ascii","ref":"string_tolowerupper_ascii","sha":"d9eab01362d379cd58fdd38498413cb914ba260e","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},"repo":{"id":30271698,"name":"coreclr","full_name":"stephentoub/coreclr","owner":{"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},"private":false,"html_url":"https://github.com/stephentoub/coreclr","description":"This repo contains the .NET Core runtime, called CoreCLR. It is an execution engine for .NET apps, performing functions such as IL byte code loading, compilation to machine code and garbage collection. The repo contains the complete up-to-date CoreCLR codebase.","fork":true,"url":"https://api.github.com/repos/stephentoub/coreclr","forks_url":"https://api.github.com/repos/stephentoub/coreclr/forks","keys_url":"https://api.github.com/repos/stephentoub/coreclr/keys{/key_id}","collaborators_url":"https://api.github.com/repos/stephentoub/coreclr/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/stephentoub/coreclr/teams","hooks_url":"https://api.github.com/repos/stephentoub/coreclr/hooks","issue_events_url":"https://api.github.com/repos/stephentoub/coreclr/issues/events{/number}","events_url":"https://api.github.com/repos/stephentoub/coreclr/events","assignees_url":"https://api.github.com/repos/stephentoub/coreclr/assignees{/user}","branches_url":"https://api.github.com/repos/stephentoub/coreclr/branches{/branch}","tags_url":"https://api.github.com/repos/stephentoub/coreclr/tags","blobs_url":"https://api.github.com/repos/stephentoub/coreclr/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/stephentoub/coreclr/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/stephentoub/coreclr/git/refs{/sha}","trees_url":"https://api.github.com/repos/stephentoub/coreclr/git/trees{/sha}","statuses_url":"https://api.github.com/repos/stephentoub/coreclr/statuses/{sha}","languages_url":"https://api.github.com/repos/stephentoub/coreclr/languages","stargazers_url":"https://api.github.com/repos/stephentoub/coreclr/stargazers","contributors_url":"https://api.github.com/repos/stephentoub/coreclr/contributors","subscribers_url":"https://api.github.com/repos/stephentoub/coreclr/subscribers","subscription_url":"https://api.github.com/repos/stephentoub/coreclr/subscription","commits_url":"https://api.github.com/repos/stephentoub/coreclr/commits{/sha}","git_commits_url":"https://api.github.com/repos/stephentoub/coreclr/git/commits{/sha}","comments_url":"https://api.github.com/repos/stephentoub/coreclr/comments{/number}","issue_comment_url":"https://api.github.com/repos/stephentoub/coreclr/issues/comments{/number}","contents_url":"https://api.github.com/repos/stephentoub/coreclr/contents/{+path}","compare_url":"https://api.github.com/repos/stephentoub/coreclr/compare/{base}...{head}","merges_url":"https://api.github.com/repos/stephentoub/coreclr/merges","archive_url":"https://api.github.com/repos/stephentoub/coreclr/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/stephentoub/coreclr/downloads","issues_url":"https://api.github.com/repos/stephentoub/coreclr/issues{/number}","pulls_url":"https://api.github.com/repos/stephentoub/coreclr/pulls{/number}","milestones_url":"https://api.github.com/repos/stephentoub/coreclr/milestones{/number}","notifications_url":"https://api.github.com/repos/stephentoub/coreclr/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/stephentoub/coreclr/labels{/name}","releases_url":"https://api.github.com/repos/stephentoub/coreclr/releases{/id}","created_at":"2015-02-04T00:05:29Z","updated_at":"2015-05-08T16:03:09Z","pushed_at":"2015-10-12T19:06:41Z","git_url":"git://github.com/stephentoub/coreclr.git","ssh_url":"git@github.com:stephentoub/coreclr.git","clone_url":"https://github.com/stephentoub/coreclr.git","svn_url":"https://github.com/stephentoub/coreclr","homepage":"","size":38828,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dotnet:master","ref":"master","sha":"1a729f8c93d03e305a1d830c9e65ca05185adcd1","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":30092893,"name":"coreclr","full_name":"dotnet/coreclr","owner":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dotnet/coreclr","description":"This repo contains the .NET Core runtime, called CoreCLR, and the base library, called mscorlib. It includes the garbage collector, JIT compiler, base .NET data types and many low-level classes.","fork":false,"url":"https://api.github.com/repos/dotnet/coreclr","forks_url":"https://api.github.com/repos/dotnet/coreclr/forks","keys_url":"https://api.github.com/repos/dotnet/coreclr/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/coreclr/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/coreclr/teams","hooks_url":"https://api.github.com/repos/dotnet/coreclr/hooks","issue_events_url":"https://api.github.com/repos/dotnet/coreclr/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/coreclr/events","assignees_url":"https://api.github.com/repos/dotnet/coreclr/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/coreclr/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/coreclr/tags","blobs_url":"https://api.github.com/repos/dotnet/coreclr/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/coreclr/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/coreclr/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/coreclr/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/coreclr/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/coreclr/languages","stargazers_url":"https://api.github.com/repos/dotnet/coreclr/stargazers","contributors_url":"https://api.github.com/repos/dotnet/coreclr/contributors","subscribers_url":"https://api.github.com/repos/dotnet/coreclr/subscribers","subscription_url":"https://api.github.com/repos/dotnet/coreclr/subscription","commits_url":"https://api.github.com/repos/dotnet/coreclr/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/coreclr/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/coreclr/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/coreclr/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/coreclr/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/coreclr/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/coreclr/merges","archive_url":"https://api.github.com/repos/dotnet/coreclr/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/coreclr/downloads","issues_url":"https://api.github.com/repos/dotnet/coreclr/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/coreclr/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/coreclr/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/coreclr/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/coreclr/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/coreclr/releases{/id}","created_at":"2015-01-30T22:10:02Z","updated_at":"2015-10-12T20:56:27Z","pushed_at":"2015-10-12T21:42:57Z","git_url":"git://github.com/dotnet/coreclr.git","ssh_url":"git@github.com:dotnet/coreclr.git","clone_url":"https://github.com/dotnet/coreclr.git","svn_url":"https://github.com/dotnet/coreclr","homepage":"http://dotnet.github.io/core/","size":57794,"stargazers_count":5266,"watchers_count":5266,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1074,"mirror_url":null,"open_issues_count":318,"forks":1074,"open_issues":318,"watchers":5266,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/coreclr/pulls/1747"},"html":{"href":"https://github.com/dotnet/coreclr/pull/1747"},"issue":{"href":"https://api.github.com/repos/dotnet/coreclr/issues/1747"},"comments":{"href":"https://api.github.com/repos/dotnet/coreclr/issues/1747/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/coreclr/pulls/1747/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/coreclr/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/coreclr/pulls/1747/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/coreclr/statuses/d9eab01362d379cd58fdd38498413cb914ba260e"}}}}