{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/comments/39985849","id":39985849,"diff_hunk":"@@ -1023,12 +1023,22 @@ public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)\n \n         public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)\n         {\n-            return ToDictionary<TSource, TKey, TSource>(source, keySelector, IdentityFunction<TSource>.Instance, null);\n+            return ToDictionary<TSource, TKey>(source, keySelector, null);\n         }\n \n         public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)\n         {\n-            return ToDictionary<TSource, TKey, TSource>(source, keySelector, IdentityFunction<TSource>.Instance, comparer);\n+            if (source == null) throw Error.ArgumentNull(\"source\");\n+            if (keySelector == null) throw Error.ArgumentNull(\"keySelector\");\n+\n+            int capacity = 0;\n+\n+            if (source is TSource[]) capacity = (source as TSource[]).Length; // Cast to Array is much faster than cast to ICollection\n+            else if (source is ICollection<TSource>) capacity = (source as ICollection<TSource>).Count;","path":"src/System.Linq/src/System/Linq/Enumerable.cs","position":17,"original_position":17,"commit_id":"4e0fe25c8d2c94b7eee8a0a38fa40057db8de72c","original_commit_id":"4e0fe25c8d2c94b7eee8a0a38fa40057db8de72c","user":{"login":"ikopylov","id":10262823,"avatar_url":"https://avatars.githubusercontent.com/u/10262823?v=3","gravatar_id":"","url":"https://api.github.com/users/ikopylov","html_url":"https://github.com/ikopylov","followers_url":"https://api.github.com/users/ikopylov/followers","following_url":"https://api.github.com/users/ikopylov/following{/other_user}","gists_url":"https://api.github.com/users/ikopylov/gists{/gist_id}","starred_url":"https://api.github.com/users/ikopylov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ikopylov/subscriptions","organizations_url":"https://api.github.com/users/ikopylov/orgs","repos_url":"https://api.github.com/users/ikopylov/repos","events_url":"https://api.github.com/users/ikopylov/events{/privacy}","received_events_url":"https://api.github.com/users/ikopylov/received_events","type":"User","site_admin":false},"body":"Cast to Array is extremely fast (if I remember correctly, it's just two comparisons). It is much much faster than to ```ICollection<T>```.\r\n\r\nCasting solely to ```ICollection<T>``` will result in performance downgrade, when the source collection is an Array, and will give almost no profit in other cases.","created_at":"2015-09-21T15:38:20Z","updated_at":"2015-09-21T15:38:20Z","html_url":"https://github.com/dotnet/corefx/pull/3338#discussion_r39985849","pull_request_url":"https://api.github.com/repos/dotnet/corefx/pulls/3338","_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments/39985849"},"html":{"href":"https://github.com/dotnet/corefx/pull/3338#discussion_r39985849"},"pull_request":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3338"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/3338","id":45504003,"html_url":"https://github.com/dotnet/corefx/pull/3338","diff_url":"https://github.com/dotnet/corefx/pull/3338.diff","patch_url":"https://github.com/dotnet/corefx/pull/3338.patch","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/3338","number":3338,"state":"open","locked":false,"title":"System.Linq ToDictionary performance improvement","user":{"login":"ikopylov","id":10262823,"avatar_url":"https://avatars.githubusercontent.com/u/10262823?v=3","gravatar_id":"","url":"https://api.github.com/users/ikopylov","html_url":"https://github.com/ikopylov","followers_url":"https://api.github.com/users/ikopylov/followers","following_url":"https://api.github.com/users/ikopylov/following{/other_user}","gists_url":"https://api.github.com/users/ikopylov/gists{/gist_id}","starred_url":"https://api.github.com/users/ikopylov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ikopylov/subscriptions","organizations_url":"https://api.github.com/users/ikopylov/orgs","repos_url":"https://api.github.com/users/ikopylov/repos","events_url":"https://api.github.com/users/ikopylov/events{/privacy}","received_events_url":"https://api.github.com/users/ikopylov/received_events","type":"User","site_admin":false},"body":"This PR is for the issue #3337.\r\n\r\nPerformance tests (_ToDictionary_Performance_ from _System.Linq.Tests_).\r\n- Original - time of execution of the original code;\r\n- Capacity est. - time of execution after capacity estimation for Array and ICollection was added;\r\n- No IdentityFunction (ms) - time of execution after special implementation of the overload without _elementSelector_ was introduced (includes capacity estimation tweak).\r\n\r\n__1000000 elements in source collection (100 iterations)__\r\n\r\nSource collection | Original (ms) | Capacity est. (ms) | Boost (%) | No IdentityFunction (ms) | Boost (%)\r\n----------------------|------------------|-------------------------|--------------|-------------------|-------\r\nArray | 3604,5024ms | 2276,9344ms | -37% | 2088,8203ms | -42%\r\nIEnumerable | 3598,2668ms | 3595,5406ms | 0% | 3424,7356ms | -5%\r\nICollection | 3591,0245ms | 2288,1238ms | -36% | 2118,0754ms | -41%\r\n\r\n\r\n__100 elements (1000000 iterations)__\r\n\r\nSource collection | Original (ms) | Capacity est. (ms) | Boost (%) | No IdentityFunction (ms) | Boost (%)\r\n----------------------|------------------|------------------------|---------------|-------------------------------|--------\r\nArray | 3289,5846ms | 2011,3236ms | -39% | 1774,5912ms | -46%\r\nIEnumerable | 3321,1946ms | 3361,5469ms | +1% | 3104,9243ms | -6%\r\nICollection | 3323,8798ms | 2049,7582ms | -38% | 1808,4537ms | -46%\r\n\r\n\r\n__4 elements (10000000 iterations)__\r\n\r\nSource collection | Original (ms) | Capacity est. (ms) | Boost (%) | No IdentityFunction (ms) | Boost (%)\r\n----------------------|------------------|------------------------|---------------|-------------------------------|--------\r\nArray | 1993,3899ms | 1480,8956ms | -26% | 1336,9621ms | -33%\r\nIEnumerable | 2322,84ms | 2404,4192ms | +3% | 2281,7706ms | -2%\r\nICollection | 2327,5683ms | 1776,3507ms | -24% | 1663,1914ms | -29%\r\n\r\n\r\n__1 element (100000000 iterations)__ /absolute time of a single iteration is very small/\r\n\r\nSource collection | Original (ms) | Capacity est. (ms) | Boost (%) | No IdentityFunction (ms) | Boost (%)\r\n----------------------|------------------|------------------------|---------------|-------------------------------|--------\r\nArray | 8167,0357ms | 8858,9957ms | +8% | 8287,586ms | +1%\r\nIEnumerable | 11219,7955ms | 12047,7075ms | +7% | 11446,0032ms | +2%\r\nICollection | 11228,2195ms | 12036,7601ms | +7% | 11382,9351ms | +1%\r\n\r\n\r\n__0 elements (100000000 iterations)__ /absolute time of a single iteration is very small/\r\n\r\nSource collection | Original (ms) | Capacity est. (ms) | Boost (%) | No IdentityFunction (ms) | Boost (%)\r\n----------------------|------------------|------------------------|---------------|-------------------------------|--------\r\nArray | 4042,6531ms | 4419,2022ms | +9% | 4192,6036ms | +3%\r\nIEnumerable | 6801,501ms | 7312,8057ms | +7% | 7154,1184ms | +5%\r\nICollection | 6782,3701ms | 7396,2199ms | +9% | 7164,335ms | +5%\r\n","created_at":"2015-09-20T20:59:51Z","updated_at":"2015-09-21T15:38:20Z","closed_at":null,"merged_at":null,"merge_commit_sha":"af73779f050636add3711de163473e81b6a8694f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/corefx/pulls/3338/commits","review_comments_url":"https://api.github.com/repos/dotnet/corefx/pulls/3338/comments","review_comment_url":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/3338/comments","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/4e0fe25c8d2c94b7eee8a0a38fa40057db8de72c","head":{"label":"ikopylov:linq_to_dictionary_perf","ref":"linq_to_dictionary_perf","sha":"4e0fe25c8d2c94b7eee8a0a38fa40057db8de72c","user":{"login":"ikopylov","id":10262823,"avatar_url":"https://avatars.githubusercontent.com/u/10262823?v=3","gravatar_id":"","url":"https://api.github.com/users/ikopylov","html_url":"https://github.com/ikopylov","followers_url":"https://api.github.com/users/ikopylov/followers","following_url":"https://api.github.com/users/ikopylov/following{/other_user}","gists_url":"https://api.github.com/users/ikopylov/gists{/gist_id}","starred_url":"https://api.github.com/users/ikopylov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ikopylov/subscriptions","organizations_url":"https://api.github.com/users/ikopylov/orgs","repos_url":"https://api.github.com/users/ikopylov/repos","events_url":"https://api.github.com/users/ikopylov/events{/privacy}","received_events_url":"https://api.github.com/users/ikopylov/received_events","type":"User","site_admin":false},"repo":{"id":32649360,"name":"corefx","full_name":"ikopylov/corefx","owner":{"login":"ikopylov","id":10262823,"avatar_url":"https://avatars.githubusercontent.com/u/10262823?v=3","gravatar_id":"","url":"https://api.github.com/users/ikopylov","html_url":"https://github.com/ikopylov","followers_url":"https://api.github.com/users/ikopylov/followers","following_url":"https://api.github.com/users/ikopylov/following{/other_user}","gists_url":"https://api.github.com/users/ikopylov/gists{/gist_id}","starred_url":"https://api.github.com/users/ikopylov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ikopylov/subscriptions","organizations_url":"https://api.github.com/users/ikopylov/orgs","repos_url":"https://api.github.com/users/ikopylov/repos","events_url":"https://api.github.com/users/ikopylov/events{/privacy}","received_events_url":"https://api.github.com/users/ikopylov/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ikopylov/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":true,"url":"https://api.github.com/repos/ikopylov/corefx","forks_url":"https://api.github.com/repos/ikopylov/corefx/forks","keys_url":"https://api.github.com/repos/ikopylov/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ikopylov/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ikopylov/corefx/teams","hooks_url":"https://api.github.com/repos/ikopylov/corefx/hooks","issue_events_url":"https://api.github.com/repos/ikopylov/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/ikopylov/corefx/events","assignees_url":"https://api.github.com/repos/ikopylov/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/ikopylov/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/ikopylov/corefx/tags","blobs_url":"https://api.github.com/repos/ikopylov/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ikopylov/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ikopylov/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/ikopylov/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ikopylov/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/ikopylov/corefx/languages","stargazers_url":"https://api.github.com/repos/ikopylov/corefx/stargazers","contributors_url":"https://api.github.com/repos/ikopylov/corefx/contributors","subscribers_url":"https://api.github.com/repos/ikopylov/corefx/subscribers","subscription_url":"https://api.github.com/repos/ikopylov/corefx/subscription","commits_url":"https://api.github.com/repos/ikopylov/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/ikopylov/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/ikopylov/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/ikopylov/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/ikopylov/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/ikopylov/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ikopylov/corefx/merges","archive_url":"https://api.github.com/repos/ikopylov/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ikopylov/corefx/downloads","issues_url":"https://api.github.com/repos/ikopylov/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/ikopylov/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/ikopylov/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/ikopylov/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ikopylov/corefx/labels{/name}","releases_url":"https://api.github.com/repos/ikopylov/corefx/releases{/id}","created_at":"2015-03-21T20:46:11Z","updated_at":"2015-03-25T20:36:19Z","pushed_at":"2015-09-20T19:50:17Z","git_url":"git://github.com/ikopylov/corefx.git","ssh_url":"git@github.com:ikopylov/corefx.git","clone_url":"https://github.com/ikopylov/corefx.git","svn_url":"https://github.com/ikopylov/corefx","homepage":"","size":31434,"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":"6134b5d33e4a6763bc34de29eb2d0949d9f33bfc","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":26295345,"name":"corefx","full_name":"dotnet/corefx","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/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":false,"url":"https://api.github.com/repos/dotnet/corefx","forks_url":"https://api.github.com/repos/dotnet/corefx/forks","keys_url":"https://api.github.com/repos/dotnet/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/corefx/teams","hooks_url":"https://api.github.com/repos/dotnet/corefx/hooks","issue_events_url":"https://api.github.com/repos/dotnet/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/corefx/events","assignees_url":"https://api.github.com/repos/dotnet/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/corefx/tags","blobs_url":"https://api.github.com/repos/dotnet/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/corefx/languages","stargazers_url":"https://api.github.com/repos/dotnet/corefx/stargazers","contributors_url":"https://api.github.com/repos/dotnet/corefx/contributors","subscribers_url":"https://api.github.com/repos/dotnet/corefx/subscribers","subscription_url":"https://api.github.com/repos/dotnet/corefx/subscription","commits_url":"https://api.github.com/repos/dotnet/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/corefx/merges","archive_url":"https://api.github.com/repos/dotnet/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/corefx/downloads","issues_url":"https://api.github.com/repos/dotnet/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/corefx/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/corefx/releases{/id}","created_at":"2014-11-06T23:42:48Z","updated_at":"2015-09-21T13:42:16Z","pushed_at":"2015-09-21T14:52:12Z","git_url":"git://github.com/dotnet/corefx.git","ssh_url":"git@github.com:dotnet/corefx.git","clone_url":"https://github.com/dotnet/corefx.git","svn_url":"https://github.com/dotnet/corefx","homepage":"http://dotnet.github.io/core/","size":68955,"stargazers_count":8365,"watchers_count":8365,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1803,"mirror_url":null,"open_issues_count":618,"forks":1803,"open_issues":618,"watchers":8365,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3338"},"html":{"href":"https://github.com/dotnet/corefx/pull/3338"},"issue":{"href":"https://api.github.com/repos/dotnet/corefx/issues/3338"},"comments":{"href":"https://api.github.com/repos/dotnet/corefx/issues/3338/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3338/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3338/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/corefx/statuses/4e0fe25c8d2c94b7eee8a0a38fa40057db8de72c"}}}}