{"action":"created","comment":{"url":"https://api.github.com/repos/fruux/sabre-vobject/pulls/comments/23463377","id":23463377,"diff_hunk":"@@ -0,0 +1,32 @@\n+<?php\n+\n+include __DIR__ . '/../vendor/autoload.php';\n+\n+if ($argc < 4) {\n+    echo \"sabre/vobject \", Sabre\\VObject\\Version::VERSION, \" RRULE benchmark\\n\";\n+    echo \"\\n\";\n+    echo \"This script can be used to measure the speed of the 'recurrence expansion'\\n\";\n+    echo \"system.\";\n+    echo \"\\n\";\n+    echo \"Usage: \" . $argv[0] . \" inputfile.ics startdate enddate\\n\";\n+    die();\n+}\n+\n+list(, $inputFile, $startDate, $endDate) = $argv;\n+\n+$bench = new Hoa\\Bench\\Bench();","path":"bin/rrulebench.php","position":17,"original_position":17,"commit_id":"28210d74e011abebee469952a9d2bc087a338e9b","original_commit_id":"28210d74e011abebee469952a9d2bc087a338e9b","user":{"login":"Hywan","id":946104,"avatar_url":"https://avatars.githubusercontent.com/u/946104?v=3","gravatar_id":"","url":"https://api.github.com/users/Hywan","html_url":"https://github.com/Hywan","followers_url":"https://api.github.com/users/Hywan/followers","following_url":"https://api.github.com/users/Hywan/following{/other_user}","gists_url":"https://api.github.com/users/Hywan/gists{/gist_id}","starred_url":"https://api.github.com/users/Hywan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Hywan/subscriptions","organizations_url":"https://api.github.com/users/Hywan/orgs","repos_url":"https://api.github.com/users/Hywan/repos","events_url":"https://api.github.com/users/Hywan/events{/privacy}","received_events_url":"https://api.github.com/users/Hywan/received_events","type":"User","site_admin":false},"body":"Ok.","created_at":"2015-01-23T16:59:23Z","updated_at":"2015-01-23T16:59:23Z","html_url":"https://github.com/fruux/sabre-vobject/pull/196#discussion_r23463377","pull_request_url":"https://api.github.com/repos/fruux/sabre-vobject/pulls/196","_links":{"self":{"href":"https://api.github.com/repos/fruux/sabre-vobject/pulls/comments/23463377"},"html":{"href":"https://github.com/fruux/sabre-vobject/pull/196#discussion_r23463377"},"pull_request":{"href":"https://api.github.com/repos/fruux/sabre-vobject/pulls/196"}}},"pull_request":{"url":"https://api.github.com/repos/fruux/sabre-vobject/pulls/196","id":27902882,"html_url":"https://github.com/fruux/sabre-vobject/pull/196","diff_url":"https://github.com/fruux/sabre-vobject/pull/196.diff","patch_url":"https://github.com/fruux/sabre-vobject/pull/196.patch","issue_url":"https://api.github.com/repos/fruux/sabre-vobject/issues/196","number":196,"state":"open","locked":false,"title":"Making the recurrence iterator faster on large calendars.","user":{"login":"evert","id":178960,"avatar_url":"https://avatars.githubusercontent.com/u/178960?v=3","gravatar_id":"","url":"https://api.github.com/users/evert","html_url":"https://github.com/evert","followers_url":"https://api.github.com/users/evert/followers","following_url":"https://api.github.com/users/evert/following{/other_user}","gists_url":"https://api.github.com/users/evert/gists{/gist_id}","starred_url":"https://api.github.com/users/evert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/evert/subscriptions","organizations_url":"https://api.github.com/users/evert/orgs","repos_url":"https://api.github.com/users/evert/repos","events_url":"https://api.github.com/users/evert/events{/privacy}","received_events_url":"https://api.github.com/users/evert/received_events","type":"User","site_admin":false},"body":"This is in response to a 5MB calendar I got from @armin-hackmann, with many, many `RRULE's` and overrides.\r\n\r\nI found out that a major slowdown actually came from traversing the list of events in VCALENDAR just to find all the events with a particular `UID`.\r\n\r\nI fixed it by doing the lookup once for the entire calendar, rather than letting the recurrence iterator do it (which does it once for every event that needs expanding).\r\n\r\nThe speed-up was quite huge.\r\n\r\n```\r\nBefore:\r\n\r\n__global__  |||||||||||||||||||||||||||||||||||||||||||||||||||| 289336ms, 100.0%\r\nparse       ||                                                   13353ms,   4.6%\r\nexpand      ||||||||||||||||||||||||||||||||||||||||||||||||||   275983ms,  95.4%\r\n\r\nAfter\r\n\r\n__global__  |||||||||||||||||||||||||||||||||||||||||||||||||||| 28022ms, 100.0%\r\nparse       |||||||||||||||||||||||||                            13632ms,  48.6%\r\nexpand      |||||||||||||||||||||||||||                          14389ms,  51.4%\r\n```\r\n\r\nThis is a 1900% increase in speed ;) \r\n\r\nOne other thing this tells me, is that grabbing values from properties is _super slow_. This is because when you do something like this:\r\n\r\n```php\r\necho $vevent->UID->getValue();\r\n```\r\n\r\nvobject will actually iterate over _every_ property defined on vevent, and see if the name matches UID.\r\nI think we can speed this up quite a bit by indexing all properties in an array by their property name.\r\n\r\nBut this will break the `$children` array, which is currently protected, so this needs to be a 4.x change.\r\n","created_at":"2015-01-23T05:56:02Z","updated_at":"2015-01-23T16:59:23Z","closed_at":null,"merged_at":null,"merge_commit_sha":"cc3d1d1cfa9f4be36eded474f749aeb4a2d9f4fc","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/fruux/sabre-vobject/pulls/196/commits","review_comments_url":"https://api.github.com/repos/fruux/sabre-vobject/pulls/196/comments","review_comment_url":"https://api.github.com/repos/fruux/sabre-vobject/pulls/comments/{number}","comments_url":"https://api.github.com/repos/fruux/sabre-vobject/issues/196/comments","statuses_url":"https://api.github.com/repos/fruux/sabre-vobject/statuses/28210d74e011abebee469952a9d2bc087a338e9b","head":{"label":"fruux:recur-optimize","ref":"recur-optimize","sha":"28210d74e011abebee469952a9d2bc087a338e9b","user":{"login":"fruux","id":1384629,"avatar_url":"https://avatars.githubusercontent.com/u/1384629?v=3","gravatar_id":"","url":"https://api.github.com/users/fruux","html_url":"https://github.com/fruux","followers_url":"https://api.github.com/users/fruux/followers","following_url":"https://api.github.com/users/fruux/following{/other_user}","gists_url":"https://api.github.com/users/fruux/gists{/gist_id}","starred_url":"https://api.github.com/users/fruux/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fruux/subscriptions","organizations_url":"https://api.github.com/users/fruux/orgs","repos_url":"https://api.github.com/users/fruux/repos","events_url":"https://api.github.com/users/fruux/events{/privacy}","received_events_url":"https://api.github.com/users/fruux/received_events","type":"Organization","site_admin":false},"repo":{"id":5299152,"name":"sabre-vobject","full_name":"fruux/sabre-vobject","owner":{"login":"fruux","id":1384629,"avatar_url":"https://avatars.githubusercontent.com/u/1384629?v=3","gravatar_id":"","url":"https://api.github.com/users/fruux","html_url":"https://github.com/fruux","followers_url":"https://api.github.com/users/fruux/followers","following_url":"https://api.github.com/users/fruux/following{/other_user}","gists_url":"https://api.github.com/users/fruux/gists{/gist_id}","starred_url":"https://api.github.com/users/fruux/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fruux/subscriptions","organizations_url":"https://api.github.com/users/fruux/orgs","repos_url":"https://api.github.com/users/fruux/repos","events_url":"https://api.github.com/users/fruux/events{/privacy}","received_events_url":"https://api.github.com/users/fruux/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/fruux/sabre-vobject","description":"The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects","fork":false,"url":"https://api.github.com/repos/fruux/sabre-vobject","forks_url":"https://api.github.com/repos/fruux/sabre-vobject/forks","keys_url":"https://api.github.com/repos/fruux/sabre-vobject/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fruux/sabre-vobject/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fruux/sabre-vobject/teams","hooks_url":"https://api.github.com/repos/fruux/sabre-vobject/hooks","issue_events_url":"https://api.github.com/repos/fruux/sabre-vobject/issues/events{/number}","events_url":"https://api.github.com/repos/fruux/sabre-vobject/events","assignees_url":"https://api.github.com/repos/fruux/sabre-vobject/assignees{/user}","branches_url":"https://api.github.com/repos/fruux/sabre-vobject/branches{/branch}","tags_url":"https://api.github.com/repos/fruux/sabre-vobject/tags","blobs_url":"https://api.github.com/repos/fruux/sabre-vobject/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fruux/sabre-vobject/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fruux/sabre-vobject/git/refs{/sha}","trees_url":"https://api.github.com/repos/fruux/sabre-vobject/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fruux/sabre-vobject/statuses/{sha}","languages_url":"https://api.github.com/repos/fruux/sabre-vobject/languages","stargazers_url":"https://api.github.com/repos/fruux/sabre-vobject/stargazers","contributors_url":"https://api.github.com/repos/fruux/sabre-vobject/contributors","subscribers_url":"https://api.github.com/repos/fruux/sabre-vobject/subscribers","subscription_url":"https://api.github.com/repos/fruux/sabre-vobject/subscription","commits_url":"https://api.github.com/repos/fruux/sabre-vobject/commits{/sha}","git_commits_url":"https://api.github.com/repos/fruux/sabre-vobject/git/commits{/sha}","comments_url":"https://api.github.com/repos/fruux/sabre-vobject/comments{/number}","issue_comment_url":"https://api.github.com/repos/fruux/sabre-vobject/issues/comments/{number}","contents_url":"https://api.github.com/repos/fruux/sabre-vobject/contents/{+path}","compare_url":"https://api.github.com/repos/fruux/sabre-vobject/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fruux/sabre-vobject/merges","archive_url":"https://api.github.com/repos/fruux/sabre-vobject/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fruux/sabre-vobject/downloads","issues_url":"https://api.github.com/repos/fruux/sabre-vobject/issues{/number}","pulls_url":"https://api.github.com/repos/fruux/sabre-vobject/pulls{/number}","milestones_url":"https://api.github.com/repos/fruux/sabre-vobject/milestones{/number}","notifications_url":"https://api.github.com/repos/fruux/sabre-vobject/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fruux/sabre-vobject/labels{/name}","releases_url":"https://api.github.com/repos/fruux/sabre-vobject/releases{/id}","created_at":"2012-08-04T22:16:41Z","updated_at":"2015-01-22T19:59:20Z","pushed_at":"2015-01-23T06:22:46Z","git_url":"git://github.com/fruux/sabre-vobject.git","ssh_url":"git@github.com:fruux/sabre-vobject.git","clone_url":"https://github.com/fruux/sabre-vobject.git","svn_url":"https://github.com/fruux/sabre-vobject","homepage":"http://sabre.io/vobject/","size":5543,"stargazers_count":189,"watchers_count":189,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":41,"mirror_url":null,"open_issues_count":17,"forks":41,"open_issues":17,"watchers":189,"default_branch":"3.3"}},"base":{"label":"fruux:3.3","ref":"3.3","sha":"97f6729787aebb5c2a8c37f5e5f6af63412d943c","user":{"login":"fruux","id":1384629,"avatar_url":"https://avatars.githubusercontent.com/u/1384629?v=3","gravatar_id":"","url":"https://api.github.com/users/fruux","html_url":"https://github.com/fruux","followers_url":"https://api.github.com/users/fruux/followers","following_url":"https://api.github.com/users/fruux/following{/other_user}","gists_url":"https://api.github.com/users/fruux/gists{/gist_id}","starred_url":"https://api.github.com/users/fruux/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fruux/subscriptions","organizations_url":"https://api.github.com/users/fruux/orgs","repos_url":"https://api.github.com/users/fruux/repos","events_url":"https://api.github.com/users/fruux/events{/privacy}","received_events_url":"https://api.github.com/users/fruux/received_events","type":"Organization","site_admin":false},"repo":{"id":5299152,"name":"sabre-vobject","full_name":"fruux/sabre-vobject","owner":{"login":"fruux","id":1384629,"avatar_url":"https://avatars.githubusercontent.com/u/1384629?v=3","gravatar_id":"","url":"https://api.github.com/users/fruux","html_url":"https://github.com/fruux","followers_url":"https://api.github.com/users/fruux/followers","following_url":"https://api.github.com/users/fruux/following{/other_user}","gists_url":"https://api.github.com/users/fruux/gists{/gist_id}","starred_url":"https://api.github.com/users/fruux/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fruux/subscriptions","organizations_url":"https://api.github.com/users/fruux/orgs","repos_url":"https://api.github.com/users/fruux/repos","events_url":"https://api.github.com/users/fruux/events{/privacy}","received_events_url":"https://api.github.com/users/fruux/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/fruux/sabre-vobject","description":"The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects","fork":false,"url":"https://api.github.com/repos/fruux/sabre-vobject","forks_url":"https://api.github.com/repos/fruux/sabre-vobject/forks","keys_url":"https://api.github.com/repos/fruux/sabre-vobject/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fruux/sabre-vobject/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fruux/sabre-vobject/teams","hooks_url":"https://api.github.com/repos/fruux/sabre-vobject/hooks","issue_events_url":"https://api.github.com/repos/fruux/sabre-vobject/issues/events{/number}","events_url":"https://api.github.com/repos/fruux/sabre-vobject/events","assignees_url":"https://api.github.com/repos/fruux/sabre-vobject/assignees{/user}","branches_url":"https://api.github.com/repos/fruux/sabre-vobject/branches{/branch}","tags_url":"https://api.github.com/repos/fruux/sabre-vobject/tags","blobs_url":"https://api.github.com/repos/fruux/sabre-vobject/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fruux/sabre-vobject/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fruux/sabre-vobject/git/refs{/sha}","trees_url":"https://api.github.com/repos/fruux/sabre-vobject/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fruux/sabre-vobject/statuses/{sha}","languages_url":"https://api.github.com/repos/fruux/sabre-vobject/languages","stargazers_url":"https://api.github.com/repos/fruux/sabre-vobject/stargazers","contributors_url":"https://api.github.com/repos/fruux/sabre-vobject/contributors","subscribers_url":"https://api.github.com/repos/fruux/sabre-vobject/subscribers","subscription_url":"https://api.github.com/repos/fruux/sabre-vobject/subscription","commits_url":"https://api.github.com/repos/fruux/sabre-vobject/commits{/sha}","git_commits_url":"https://api.github.com/repos/fruux/sabre-vobject/git/commits{/sha}","comments_url":"https://api.github.com/repos/fruux/sabre-vobject/comments{/number}","issue_comment_url":"https://api.github.com/repos/fruux/sabre-vobject/issues/comments/{number}","contents_url":"https://api.github.com/repos/fruux/sabre-vobject/contents/{+path}","compare_url":"https://api.github.com/repos/fruux/sabre-vobject/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fruux/sabre-vobject/merges","archive_url":"https://api.github.com/repos/fruux/sabre-vobject/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fruux/sabre-vobject/downloads","issues_url":"https://api.github.com/repos/fruux/sabre-vobject/issues{/number}","pulls_url":"https://api.github.com/repos/fruux/sabre-vobject/pulls{/number}","milestones_url":"https://api.github.com/repos/fruux/sabre-vobject/milestones{/number}","notifications_url":"https://api.github.com/repos/fruux/sabre-vobject/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fruux/sabre-vobject/labels{/name}","releases_url":"https://api.github.com/repos/fruux/sabre-vobject/releases{/id}","created_at":"2012-08-04T22:16:41Z","updated_at":"2015-01-22T19:59:20Z","pushed_at":"2015-01-23T06:22:46Z","git_url":"git://github.com/fruux/sabre-vobject.git","ssh_url":"git@github.com:fruux/sabre-vobject.git","clone_url":"https://github.com/fruux/sabre-vobject.git","svn_url":"https://github.com/fruux/sabre-vobject","homepage":"http://sabre.io/vobject/","size":5543,"stargazers_count":189,"watchers_count":189,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":41,"mirror_url":null,"open_issues_count":17,"forks":41,"open_issues":17,"watchers":189,"default_branch":"3.3"}},"_links":{"self":{"href":"https://api.github.com/repos/fruux/sabre-vobject/pulls/196"},"html":{"href":"https://github.com/fruux/sabre-vobject/pull/196"},"issue":{"href":"https://api.github.com/repos/fruux/sabre-vobject/issues/196"},"comments":{"href":"https://api.github.com/repos/fruux/sabre-vobject/issues/196/comments"},"review_comments":{"href":"https://api.github.com/repos/fruux/sabre-vobject/pulls/196/comments"},"review_comment":{"href":"https://api.github.com/repos/fruux/sabre-vobject/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/fruux/sabre-vobject/pulls/196/commits"},"statuses":{"href":"https://api.github.com/repos/fruux/sabre-vobject/statuses/28210d74e011abebee469952a9d2bc087a338e9b"}}}}