{"action":"created","comment":{"url":"https://api.github.com/repos/Shopify/liquid/pulls/comments/49009319","id":49009319,"diff_hunk":"@@ -170,6 +114,74 @@ def strict_parse(markup)\n \n     private\n \n+    def collection_segment(context)\n+      offsets = context.registers[:for] ||= Hash.new(0)\n+\n+      from = if @from == :continue\n+        offsets[@name].to_i\n+      else\n+        context.evaluate(@from).to_i\n+      end\n+\n+      collection = context.evaluate(@collection_name)\n+      collection = collection.to_a if collection.is_a?(Range)\n+\n+      limit = context.evaluate(@limit)\n+      to = limit ? limit.to_i + from : nil\n+\n+      segment = Utils.slice_collection(collection, from, to)\n+      segment.reverse! if @reversed\n+\n+      offsets[@name] = from + segment.length\n+\n+      segment\n+    end\n+\n+    def render_segment(context, segment)\n+      for_stack = context.registers[:for_stack] ||= []\n+      length = segment.length\n+\n+      result = ''\n+\n+      context.stack do\n+        loop_vars = {\n+          'name'.freeze => @name,\n+          'length'.freeze => length,\n+          'parentloop'.freeze => for_stack[-1]\n+        }\n+\n+        for_stack.push(loop_vars)\n+\n+        begin\n+          context['forloop'.freeze] = loop_vars\n+\n+          segment.each_with_index do |item, index|\n+            context[@variable_name] = item\n+\n+            loop_vars['index'.freeze] = index + 1\n+            loop_vars['index0'.freeze] = index\n+            loop_vars['rindex'.freeze] = length - index\n+            loop_vars['rindex0'.freeze] = length - index - 1\n+            loop_vars['first'.freeze] = (index == 0)\n+            loop_vars['last'.freeze] = (index == length - 1)","path":"lib/liquid/tags/for.rb","position":127,"original_position":127,"commit_id":"1662ba6679f6993d3a8b041813f9baac999150a0","original_commit_id":"1662ba6679f6993d3a8b041813f9baac999150a0","user":{"login":"fw42","id":2072686,"avatar_url":"https://avatars.githubusercontent.com/u/2072686?v=3","gravatar_id":"","url":"https://api.github.com/users/fw42","html_url":"https://github.com/fw42","followers_url":"https://api.github.com/users/fw42/followers","following_url":"https://api.github.com/users/fw42/following{/other_user}","gists_url":"https://api.github.com/users/fw42/gists{/gist_id}","starred_url":"https://api.github.com/users/fw42/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fw42/subscriptions","organizations_url":"https://api.github.com/users/fw42/orgs","repos_url":"https://api.github.com/users/fw42/repos","events_url":"https://api.github.com/users/fw42/events{/privacy}","received_events_url":"https://api.github.com/users/fw42/received_events","type":"User","site_admin":false},"body":"hm interesting idea, I will try that","created_at":"2016-01-06T21:05:08Z","updated_at":"2016-01-06T21:05:08Z","html_url":"https://github.com/Shopify/liquid/pull/681#discussion_r49009319","pull_request_url":"https://api.github.com/repos/Shopify/liquid/pulls/681","_links":{"self":{"href":"https://api.github.com/repos/Shopify/liquid/pulls/comments/49009319"},"html":{"href":"https://github.com/Shopify/liquid/pull/681#discussion_r49009319"},"pull_request":{"href":"https://api.github.com/repos/Shopify/liquid/pulls/681"}}},"pull_request":{"url":"https://api.github.com/repos/Shopify/liquid/pulls/681","id":55260923,"html_url":"https://github.com/Shopify/liquid/pull/681","diff_url":"https://github.com/Shopify/liquid/pull/681.diff","patch_url":"https://github.com/Shopify/liquid/pull/681.patch","issue_url":"https://api.github.com/repos/Shopify/liquid/issues/681","number":681,"state":"open","locked":false,"title":"Reuse 'forloop' hash to save memory allocations","user":{"login":"fw42","id":2072686,"avatar_url":"https://avatars.githubusercontent.com/u/2072686?v=3","gravatar_id":"","url":"https://api.github.com/users/fw42","html_url":"https://github.com/fw42","followers_url":"https://api.github.com/users/fw42/followers","following_url":"https://api.github.com/users/fw42/following{/other_user}","gists_url":"https://api.github.com/users/fw42/gists{/gist_id}","starred_url":"https://api.github.com/users/fw42/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fw42/subscriptions","organizations_url":"https://api.github.com/users/fw42/orgs","repos_url":"https://api.github.com/users/fw42/repos","events_url":"https://api.github.com/users/fw42/events{/privacy}","received_events_url":"https://api.github.com/users/fw42/received_events","type":"User","site_admin":false},"body":"Tries to address https://github.com/Shopify/liquid/issues/678.\r\n\r\nNot sure if this makes sense or if there is some side-effects that I'm missing (but if I am, then at least this PR should reveal some missing test coverage, since everything is green).\r\n\r\nBefore:\r\n```\r\n                          user     system      total        real\r\nruby_empty_loop        0.030000   0.000000   0.030000 (  0.026284)\r\nfor_loop_no_body       0.840000   0.010000   0.850000 (  0.853402)\r\nfor_loop_with_body     1.800000   0.000000   1.800000 (  1.807363)\r\n```\r\n\r\nAfter:\r\n```\r\n                           user     system      total        real\r\nruby_empty_loop        0.030000   0.000000   0.030000 (  0.027673)\r\nfor_loop_no_body       0.430000   0.000000   0.430000 (  0.430292)\r\nfor_loop_with_body     1.240000   0.010000   1.250000 (  1.259245)\r\n```\r\n\r\n(See https://github.com/Shopify/liquid/issues/678 for the benchmark script I'm using.)\r\n\r\nThe idea here is that I don't see any reason why consecutive loop iterations each create a new Hash Ruby object for the `forloop` variable. Instead, re-use the one from the previous iteration and just update the keys (if necessary).\r\n\r\nAlso refactor the `For#render` method a little bit to (hopefully) make it a bit more readable, it was getting pretty long and hairy.\r\n\r\n@dylanahsmith @pushrax ","created_at":"2016-01-06T20:34:20Z","updated_at":"2016-01-06T21:05:08Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4ac37a2fe1f71cb96aa7ad3a4d5606a77cd26199","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Shopify/liquid/pulls/681/commits","review_comments_url":"https://api.github.com/repos/Shopify/liquid/pulls/681/comments","review_comment_url":"https://api.github.com/repos/Shopify/liquid/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Shopify/liquid/issues/681/comments","statuses_url":"https://api.github.com/repos/Shopify/liquid/statuses/1662ba6679f6993d3a8b041813f9baac999150a0","head":{"label":"Shopify:save-some-loop-allocations","ref":"save-some-loop-allocations","sha":"1662ba6679f6993d3a8b041813f9baac999150a0","user":{"login":"Shopify","id":8085,"avatar_url":"https://avatars.githubusercontent.com/u/8085?v=3","gravatar_id":"","url":"https://api.github.com/users/Shopify","html_url":"https://github.com/Shopify","followers_url":"https://api.github.com/users/Shopify/followers","following_url":"https://api.github.com/users/Shopify/following{/other_user}","gists_url":"https://api.github.com/users/Shopify/gists{/gist_id}","starred_url":"https://api.github.com/users/Shopify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Shopify/subscriptions","organizations_url":"https://api.github.com/users/Shopify/orgs","repos_url":"https://api.github.com/users/Shopify/repos","events_url":"https://api.github.com/users/Shopify/events{/privacy}","received_events_url":"https://api.github.com/users/Shopify/received_events","type":"Organization","site_admin":false},"repo":{"id":15435,"name":"liquid","full_name":"Shopify/liquid","owner":{"login":"Shopify","id":8085,"avatar_url":"https://avatars.githubusercontent.com/u/8085?v=3","gravatar_id":"","url":"https://api.github.com/users/Shopify","html_url":"https://github.com/Shopify","followers_url":"https://api.github.com/users/Shopify/followers","following_url":"https://api.github.com/users/Shopify/following{/other_user}","gists_url":"https://api.github.com/users/Shopify/gists{/gist_id}","starred_url":"https://api.github.com/users/Shopify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Shopify/subscriptions","organizations_url":"https://api.github.com/users/Shopify/orgs","repos_url":"https://api.github.com/users/Shopify/repos","events_url":"https://api.github.com/users/Shopify/events{/privacy}","received_events_url":"https://api.github.com/users/Shopify/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Shopify/liquid","description":"Liquid markup language. Safe, customer facing template language for flexible web apps. ","fork":false,"url":"https://api.github.com/repos/Shopify/liquid","forks_url":"https://api.github.com/repos/Shopify/liquid/forks","keys_url":"https://api.github.com/repos/Shopify/liquid/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Shopify/liquid/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Shopify/liquid/teams","hooks_url":"https://api.github.com/repos/Shopify/liquid/hooks","issue_events_url":"https://api.github.com/repos/Shopify/liquid/issues/events{/number}","events_url":"https://api.github.com/repos/Shopify/liquid/events","assignees_url":"https://api.github.com/repos/Shopify/liquid/assignees{/user}","branches_url":"https://api.github.com/repos/Shopify/liquid/branches{/branch}","tags_url":"https://api.github.com/repos/Shopify/liquid/tags","blobs_url":"https://api.github.com/repos/Shopify/liquid/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Shopify/liquid/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Shopify/liquid/git/refs{/sha}","trees_url":"https://api.github.com/repos/Shopify/liquid/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Shopify/liquid/statuses/{sha}","languages_url":"https://api.github.com/repos/Shopify/liquid/languages","stargazers_url":"https://api.github.com/repos/Shopify/liquid/stargazers","contributors_url":"https://api.github.com/repos/Shopify/liquid/contributors","subscribers_url":"https://api.github.com/repos/Shopify/liquid/subscribers","subscription_url":"https://api.github.com/repos/Shopify/liquid/subscription","commits_url":"https://api.github.com/repos/Shopify/liquid/commits{/sha}","git_commits_url":"https://api.github.com/repos/Shopify/liquid/git/commits{/sha}","comments_url":"https://api.github.com/repos/Shopify/liquid/comments{/number}","issue_comment_url":"https://api.github.com/repos/Shopify/liquid/issues/comments{/number}","contents_url":"https://api.github.com/repos/Shopify/liquid/contents/{+path}","compare_url":"https://api.github.com/repos/Shopify/liquid/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Shopify/liquid/merges","archive_url":"https://api.github.com/repos/Shopify/liquid/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Shopify/liquid/downloads","issues_url":"https://api.github.com/repos/Shopify/liquid/issues{/number}","pulls_url":"https://api.github.com/repos/Shopify/liquid/pulls{/number}","milestones_url":"https://api.github.com/repos/Shopify/liquid/milestones{/number}","notifications_url":"https://api.github.com/repos/Shopify/liquid/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Shopify/liquid/labels{/name}","releases_url":"https://api.github.com/repos/Shopify/liquid/releases{/id}","created_at":"2008-05-08T15:27:26Z","updated_at":"2016-01-06T06:55:53Z","pushed_at":"2016-01-06T20:59:55Z","git_url":"git://github.com/Shopify/liquid.git","ssh_url":"git@github.com:Shopify/liquid.git","clone_url":"https://github.com/Shopify/liquid.git","svn_url":"https://github.com/Shopify/liquid","homepage":"http://liquidmarkup.org/","size":4711,"stargazers_count":3971,"watchers_count":3971,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":542,"mirror_url":null,"open_issues_count":38,"forks":542,"open_issues":38,"watchers":3971,"default_branch":"master"}},"base":{"label":"Shopify:master","ref":"master","sha":"99b5e86f0ad7f0dac56bbc88d948abb4876e1880","user":{"login":"Shopify","id":8085,"avatar_url":"https://avatars.githubusercontent.com/u/8085?v=3","gravatar_id":"","url":"https://api.github.com/users/Shopify","html_url":"https://github.com/Shopify","followers_url":"https://api.github.com/users/Shopify/followers","following_url":"https://api.github.com/users/Shopify/following{/other_user}","gists_url":"https://api.github.com/users/Shopify/gists{/gist_id}","starred_url":"https://api.github.com/users/Shopify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Shopify/subscriptions","organizations_url":"https://api.github.com/users/Shopify/orgs","repos_url":"https://api.github.com/users/Shopify/repos","events_url":"https://api.github.com/users/Shopify/events{/privacy}","received_events_url":"https://api.github.com/users/Shopify/received_events","type":"Organization","site_admin":false},"repo":{"id":15435,"name":"liquid","full_name":"Shopify/liquid","owner":{"login":"Shopify","id":8085,"avatar_url":"https://avatars.githubusercontent.com/u/8085?v=3","gravatar_id":"","url":"https://api.github.com/users/Shopify","html_url":"https://github.com/Shopify","followers_url":"https://api.github.com/users/Shopify/followers","following_url":"https://api.github.com/users/Shopify/following{/other_user}","gists_url":"https://api.github.com/users/Shopify/gists{/gist_id}","starred_url":"https://api.github.com/users/Shopify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Shopify/subscriptions","organizations_url":"https://api.github.com/users/Shopify/orgs","repos_url":"https://api.github.com/users/Shopify/repos","events_url":"https://api.github.com/users/Shopify/events{/privacy}","received_events_url":"https://api.github.com/users/Shopify/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Shopify/liquid","description":"Liquid markup language. Safe, customer facing template language for flexible web apps. ","fork":false,"url":"https://api.github.com/repos/Shopify/liquid","forks_url":"https://api.github.com/repos/Shopify/liquid/forks","keys_url":"https://api.github.com/repos/Shopify/liquid/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Shopify/liquid/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Shopify/liquid/teams","hooks_url":"https://api.github.com/repos/Shopify/liquid/hooks","issue_events_url":"https://api.github.com/repos/Shopify/liquid/issues/events{/number}","events_url":"https://api.github.com/repos/Shopify/liquid/events","assignees_url":"https://api.github.com/repos/Shopify/liquid/assignees{/user}","branches_url":"https://api.github.com/repos/Shopify/liquid/branches{/branch}","tags_url":"https://api.github.com/repos/Shopify/liquid/tags","blobs_url":"https://api.github.com/repos/Shopify/liquid/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Shopify/liquid/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Shopify/liquid/git/refs{/sha}","trees_url":"https://api.github.com/repos/Shopify/liquid/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Shopify/liquid/statuses/{sha}","languages_url":"https://api.github.com/repos/Shopify/liquid/languages","stargazers_url":"https://api.github.com/repos/Shopify/liquid/stargazers","contributors_url":"https://api.github.com/repos/Shopify/liquid/contributors","subscribers_url":"https://api.github.com/repos/Shopify/liquid/subscribers","subscription_url":"https://api.github.com/repos/Shopify/liquid/subscription","commits_url":"https://api.github.com/repos/Shopify/liquid/commits{/sha}","git_commits_url":"https://api.github.com/repos/Shopify/liquid/git/commits{/sha}","comments_url":"https://api.github.com/repos/Shopify/liquid/comments{/number}","issue_comment_url":"https://api.github.com/repos/Shopify/liquid/issues/comments{/number}","contents_url":"https://api.github.com/repos/Shopify/liquid/contents/{+path}","compare_url":"https://api.github.com/repos/Shopify/liquid/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Shopify/liquid/merges","archive_url":"https://api.github.com/repos/Shopify/liquid/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Shopify/liquid/downloads","issues_url":"https://api.github.com/repos/Shopify/liquid/issues{/number}","pulls_url":"https://api.github.com/repos/Shopify/liquid/pulls{/number}","milestones_url":"https://api.github.com/repos/Shopify/liquid/milestones{/number}","notifications_url":"https://api.github.com/repos/Shopify/liquid/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Shopify/liquid/labels{/name}","releases_url":"https://api.github.com/repos/Shopify/liquid/releases{/id}","created_at":"2008-05-08T15:27:26Z","updated_at":"2016-01-06T06:55:53Z","pushed_at":"2016-01-06T20:59:55Z","git_url":"git://github.com/Shopify/liquid.git","ssh_url":"git@github.com:Shopify/liquid.git","clone_url":"https://github.com/Shopify/liquid.git","svn_url":"https://github.com/Shopify/liquid","homepage":"http://liquidmarkup.org/","size":4711,"stargazers_count":3971,"watchers_count":3971,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":542,"mirror_url":null,"open_issues_count":38,"forks":542,"open_issues":38,"watchers":3971,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Shopify/liquid/pulls/681"},"html":{"href":"https://github.com/Shopify/liquid/pull/681"},"issue":{"href":"https://api.github.com/repos/Shopify/liquid/issues/681"},"comments":{"href":"https://api.github.com/repos/Shopify/liquid/issues/681/comments"},"review_comments":{"href":"https://api.github.com/repos/Shopify/liquid/pulls/681/comments"},"review_comment":{"href":"https://api.github.com/repos/Shopify/liquid/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Shopify/liquid/pulls/681/commits"},"statuses":{"href":"https://api.github.com/repos/Shopify/liquid/statuses/1662ba6679f6993d3a8b041813f9baac999150a0"}}}}