{"action":"closed","number":124,"pull_request":{"url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/pulls/124","id":63474187,"html_url":"https://github.com/PerfDotNet/BenchmarkDotNet/pull/124","diff_url":"https://github.com/PerfDotNet/BenchmarkDotNet/pull/124.diff","patch_url":"https://github.com/PerfDotNet/BenchmarkDotNet/pull/124.patch","issue_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/issues/124","number":124,"state":"closed","locked":false,"title":"Faster export","user":{"login":"adamsitnik","id":6011991,"avatar_url":"https://avatars.githubusercontent.com/u/6011991?v=3","gravatar_id":"","url":"https://api.github.com/users/adamsitnik","html_url":"https://github.com/adamsitnik","followers_url":"https://api.github.com/users/adamsitnik/followers","following_url":"https://api.github.com/users/adamsitnik/following{/other_user}","gists_url":"https://api.github.com/users/adamsitnik/gists{/gist_id}","starred_url":"https://api.github.com/users/adamsitnik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adamsitnik/subscriptions","organizations_url":"https://api.github.com/users/adamsitnik/orgs","repos_url":"https://api.github.com/users/adamsitnik/repos","events_url":"https://api.github.com/users/adamsitnik/events{/privacy}","received_events_url":"https://api.github.com/users/adamsitnik/received_events","type":"User","site_admin":false},"body":"In general I have simplified and optimized loging/export. For [this case](https://github.com/PerfDotNet/BenchmarkDotNet/issues/119) the time went from 2 hours 46 minutes to 2 minutes.\r\n\r\nChanges in the code:\r\n* reduced computional complexity\r\n* reduced number of allocations\r\n* caching and reusing expensive things\r\n* some refactoring\r\n* export is done in deffered way now, so at the end of benchmark run each exported file is printed right after it is exported, not after all files are exported . User can now see the progress\r\n* **disadvantage** when calling logger.Write you need to take care of the CurrentCulture on your own. It also no longer supports 'params'. (To save time on allocations)\r\n\r\nThe \"hottest path\" was in CsvMeasurementsExporter:\r\n\r\n```\r\nforeach (var report in reports)\r\n{\r\n   foreach (var measurement in report.AllMeasurements)\r\n      logger.WriteLine(string.Join(\";\", columns.Select(column => column.GetValue(summary, report, measurement))));\r\n}\r\n```\r\n\r\nfor \"Job\" column, which was calling 'report.Benchmark.Job.GetShortInfo(GetJobs(summary)))'\r\n\r\nwhich was:\r\n```\r\nvar defaultJobProperties = Job.Default.GetAllProperties().ToArray();\r\n            var ownProperties = job.GetAllProperties().ToArray();\r\n            var n = ownProperties.Length;\r\n            var targetProperties = Enumerable.Range(0, n).\r\n                Where(i => ownProperties[i].Value != defaultJobProperties[i].Value &&\r\n                           allJobs.Select(j => j.GetAllProperties().ToArray()[i].Value).Distinct().Count() > 1).\r\n                Select(i => ownProperties[i]);\r\n            return string.Join(\"_\", targetProperties.Select(GetShortInfoForProperty));\r\n```\r\n\r\nso the complexity for pessimistic scenario was O(reportsCount * measurementsCount * propertiesCount * jobsCount) and doing a lot of allocations.\r\n\r\n\r\n\r\n","created_at":"2016-03-19T18:00:07Z","updated_at":"2016-03-23T05:21:12Z","closed_at":"2016-03-23T05:21:12Z","merged_at":"2016-03-23T05:21:12Z","merge_commit_sha":"582e08929566b41fa48f1cb76a468e344d872937","assignee":null,"milestone":{"url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/milestones/2","html_url":"https://github.com/PerfDotNet/BenchmarkDotNet/milestones/v0.9.4","labels_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/milestones/2/labels","id":1623453,"number":2,"title":"v0.9.4","description":"","creator":{"login":"AndreyAkinshin","id":2259237,"avatar_url":"https://avatars.githubusercontent.com/u/2259237?v=3","gravatar_id":"","url":"https://api.github.com/users/AndreyAkinshin","html_url":"https://github.com/AndreyAkinshin","followers_url":"https://api.github.com/users/AndreyAkinshin/followers","following_url":"https://api.github.com/users/AndreyAkinshin/following{/other_user}","gists_url":"https://api.github.com/users/AndreyAkinshin/gists{/gist_id}","starred_url":"https://api.github.com/users/AndreyAkinshin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AndreyAkinshin/subscriptions","organizations_url":"https://api.github.com/users/AndreyAkinshin/orgs","repos_url":"https://api.github.com/users/AndreyAkinshin/repos","events_url":"https://api.github.com/users/AndreyAkinshin/events{/privacy}","received_events_url":"https://api.github.com/users/AndreyAkinshin/received_events","type":"User","site_admin":false},"open_issues":4,"closed_issues":4,"state":"open","created_at":"2016-03-05T05:11:18Z","updated_at":"2016-03-23T05:21:12Z","due_on":"2016-03-15T22:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/pulls/124/commits","review_comments_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/pulls/124/comments","review_comment_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/pulls/comments{/number}","comments_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/issues/124/comments","statuses_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/statuses/40071d68dc3ab84b51588013aa2c61b56946524d","head":{"label":"PerfDotNet:perf","ref":"perf","sha":"40071d68dc3ab84b51588013aa2c61b56946524d","user":{"login":"PerfDotNet","id":12517848,"avatar_url":"https://avatars.githubusercontent.com/u/12517848?v=3","gravatar_id":"","url":"https://api.github.com/users/PerfDotNet","html_url":"https://github.com/PerfDotNet","followers_url":"https://api.github.com/users/PerfDotNet/followers","following_url":"https://api.github.com/users/PerfDotNet/following{/other_user}","gists_url":"https://api.github.com/users/PerfDotNet/gists{/gist_id}","starred_url":"https://api.github.com/users/PerfDotNet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PerfDotNet/subscriptions","organizations_url":"https://api.github.com/users/PerfDotNet/orgs","repos_url":"https://api.github.com/users/PerfDotNet/repos","events_url":"https://api.github.com/users/PerfDotNet/events{/privacy}","received_events_url":"https://api.github.com/users/PerfDotNet/received_events","type":"Organization","site_admin":false},"repo":{"id":12191244,"name":"BenchmarkDotNet","full_name":"PerfDotNet/BenchmarkDotNet","owner":{"login":"PerfDotNet","id":12517848,"avatar_url":"https://avatars.githubusercontent.com/u/12517848?v=3","gravatar_id":"","url":"https://api.github.com/users/PerfDotNet","html_url":"https://github.com/PerfDotNet","followers_url":"https://api.github.com/users/PerfDotNet/followers","following_url":"https://api.github.com/users/PerfDotNet/following{/other_user}","gists_url":"https://api.github.com/users/PerfDotNet/gists{/gist_id}","starred_url":"https://api.github.com/users/PerfDotNet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PerfDotNet/subscriptions","organizations_url":"https://api.github.com/users/PerfDotNet/orgs","repos_url":"https://api.github.com/users/PerfDotNet/repos","events_url":"https://api.github.com/users/PerfDotNet/events{/privacy}","received_events_url":"https://api.github.com/users/PerfDotNet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/PerfDotNet/BenchmarkDotNet","description":"Powerful .NET library for benchmarking","fork":false,"url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet","forks_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/forks","keys_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/teams","hooks_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/hooks","issue_events_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/issues/events{/number}","events_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/events","assignees_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/assignees{/user}","branches_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/branches{/branch}","tags_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/tags","blobs_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/git/refs{/sha}","trees_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/statuses/{sha}","languages_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/languages","stargazers_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/stargazers","contributors_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/contributors","subscribers_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/subscribers","subscription_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/subscription","commits_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/commits{/sha}","git_commits_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/git/commits{/sha}","comments_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/comments{/number}","issue_comment_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/issues/comments{/number}","contents_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/contents/{+path}","compare_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/merges","archive_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/downloads","issues_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/issues{/number}","pulls_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/pulls{/number}","milestones_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/milestones{/number}","notifications_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/labels{/name}","releases_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/releases{/id}","deployments_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/deployments","created_at":"2013-08-18T06:17:48Z","updated_at":"2016-03-23T04:13:45Z","pushed_at":"2016-03-23T05:21:12Z","git_url":"git://github.com/PerfDotNet/BenchmarkDotNet.git","ssh_url":"git@github.com:PerfDotNet/BenchmarkDotNet.git","clone_url":"https://github.com/PerfDotNet/BenchmarkDotNet.git","svn_url":"https://github.com/PerfDotNet/BenchmarkDotNet","homepage":"https://www.nuget.org/packages/BenchmarkDotNet/","size":4723,"stargazers_count":891,"watchers_count":891,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":67,"mirror_url":null,"open_issues_count":45,"forks":67,"open_issues":45,"watchers":891,"default_branch":"master"}},"base":{"label":"PerfDotNet:develop","ref":"develop","sha":"a4d0b85d8b9358b0d4f421e6c332b9d649099212","user":{"login":"PerfDotNet","id":12517848,"avatar_url":"https://avatars.githubusercontent.com/u/12517848?v=3","gravatar_id":"","url":"https://api.github.com/users/PerfDotNet","html_url":"https://github.com/PerfDotNet","followers_url":"https://api.github.com/users/PerfDotNet/followers","following_url":"https://api.github.com/users/PerfDotNet/following{/other_user}","gists_url":"https://api.github.com/users/PerfDotNet/gists{/gist_id}","starred_url":"https://api.github.com/users/PerfDotNet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PerfDotNet/subscriptions","organizations_url":"https://api.github.com/users/PerfDotNet/orgs","repos_url":"https://api.github.com/users/PerfDotNet/repos","events_url":"https://api.github.com/users/PerfDotNet/events{/privacy}","received_events_url":"https://api.github.com/users/PerfDotNet/received_events","type":"Organization","site_admin":false},"repo":{"id":12191244,"name":"BenchmarkDotNet","full_name":"PerfDotNet/BenchmarkDotNet","owner":{"login":"PerfDotNet","id":12517848,"avatar_url":"https://avatars.githubusercontent.com/u/12517848?v=3","gravatar_id":"","url":"https://api.github.com/users/PerfDotNet","html_url":"https://github.com/PerfDotNet","followers_url":"https://api.github.com/users/PerfDotNet/followers","following_url":"https://api.github.com/users/PerfDotNet/following{/other_user}","gists_url":"https://api.github.com/users/PerfDotNet/gists{/gist_id}","starred_url":"https://api.github.com/users/PerfDotNet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PerfDotNet/subscriptions","organizations_url":"https://api.github.com/users/PerfDotNet/orgs","repos_url":"https://api.github.com/users/PerfDotNet/repos","events_url":"https://api.github.com/users/PerfDotNet/events{/privacy}","received_events_url":"https://api.github.com/users/PerfDotNet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/PerfDotNet/BenchmarkDotNet","description":"Powerful .NET library for benchmarking","fork":false,"url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet","forks_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/forks","keys_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/teams","hooks_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/hooks","issue_events_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/issues/events{/number}","events_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/events","assignees_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/assignees{/user}","branches_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/branches{/branch}","tags_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/tags","blobs_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/git/refs{/sha}","trees_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/statuses/{sha}","languages_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/languages","stargazers_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/stargazers","contributors_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/contributors","subscribers_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/subscribers","subscription_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/subscription","commits_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/commits{/sha}","git_commits_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/git/commits{/sha}","comments_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/comments{/number}","issue_comment_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/issues/comments{/number}","contents_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/contents/{+path}","compare_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/merges","archive_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/downloads","issues_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/issues{/number}","pulls_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/pulls{/number}","milestones_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/milestones{/number}","notifications_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/labels{/name}","releases_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/releases{/id}","deployments_url":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/deployments","created_at":"2013-08-18T06:17:48Z","updated_at":"2016-03-23T04:13:45Z","pushed_at":"2016-03-23T05:21:12Z","git_url":"git://github.com/PerfDotNet/BenchmarkDotNet.git","ssh_url":"git@github.com:PerfDotNet/BenchmarkDotNet.git","clone_url":"https://github.com/PerfDotNet/BenchmarkDotNet.git","svn_url":"https://github.com/PerfDotNet/BenchmarkDotNet","homepage":"https://www.nuget.org/packages/BenchmarkDotNet/","size":4723,"stargazers_count":891,"watchers_count":891,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":67,"mirror_url":null,"open_issues_count":45,"forks":67,"open_issues":45,"watchers":891,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/pulls/124"},"html":{"href":"https://github.com/PerfDotNet/BenchmarkDotNet/pull/124"},"issue":{"href":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/issues/124"},"comments":{"href":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/issues/124/comments"},"review_comments":{"href":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/pulls/124/comments"},"review_comment":{"href":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/pulls/124/commits"},"statuses":{"href":"https://api.github.com/repos/PerfDotNet/BenchmarkDotNet/statuses/40071d68dc3ab84b51588013aa2c61b56946524d"}},"merged":true,"mergeable":null,"mergeable_state":"unknown","merged_by":{"login":"AndreyAkinshin","id":2259237,"avatar_url":"https://avatars.githubusercontent.com/u/2259237?v=3","gravatar_id":"","url":"https://api.github.com/users/AndreyAkinshin","html_url":"https://github.com/AndreyAkinshin","followers_url":"https://api.github.com/users/AndreyAkinshin/followers","following_url":"https://api.github.com/users/AndreyAkinshin/following{/other_user}","gists_url":"https://api.github.com/users/AndreyAkinshin/gists{/gist_id}","starred_url":"https://api.github.com/users/AndreyAkinshin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AndreyAkinshin/subscriptions","organizations_url":"https://api.github.com/users/AndreyAkinshin/orgs","repos_url":"https://api.github.com/users/AndreyAkinshin/repos","events_url":"https://api.github.com/users/AndreyAkinshin/events{/privacy}","received_events_url":"https://api.github.com/users/AndreyAkinshin/received_events","type":"User","site_admin":false},"comments":0,"review_comments":0,"commits":7,"additions":547,"deletions":294,"changed_files":33}}