{"action":"created","comment":{"url":"https://api.github.com/repos/erlang/otp/pulls/comments/92173544","pull_request_review_id":12683002,"id":92173544,"diff_hunk":"@@ -35,80 +35,29 @@\n   <marker id=\"myths\"></marker>\n   <p>Some truths seem to live on well beyond their best-before date,\n   perhaps because \"information\" spreads faster from person-to-person\n-  than a single release note that says, for example, that funs\n-  have become faster.</p>\n+  than a single release note that says, for example, that body-recursive\n+  calls have become faster.</p>\n \n   <p>This section tries to kill the old truths (or semi-truths) that have\n   become myths.</p>\n \n   <section>\n-    <title>Myth: Funs are Slow</title>\n-    <p>Funs used to be very slow, slower than <c>apply/3</c>.\n-    Originally, funs were implemented using nothing more than\n-    compiler trickery, ordinary tuples, <c>apply/3</c>, and a great\n-    deal of ingenuity.</p>\n-\n-    <p>But that is history. Funs was given its own data type\n-    in R6B and was further optimized in R7B.\n-    Now the cost for a fun call falls roughly between the cost for a call\n-    to a local function and <c>apply/3</c>.</p>\n-  </section>\n-\n-  <section>\n-    <title>Myth: List Comprehensions are Slow</title>\n-\n-    <p>List comprehensions used to be implemented using funs, and in the\n-    old days funs were indeed slow.</p>\n-\n-    <p>Nowadays, the compiler rewrites list comprehensions into an ordinary\n-    recursive function. Using a tail-recursive function with\n-    a reverse at the end would be still faster. Or would it?\n-    That leads us to the next myth.</p>\n-  </section>\n-\n-  <section>\n     <title>Myth: Tail-Recursive Functions are Much Faster\n     Than Recursive Functions</title>\n \n     <p><marker id=\"tail_recursive\"></marker>According to the myth,\n-    recursive functions leave references\n-    to dead terms on the stack and the garbage collector has to copy\n-    all those dead terms, while tail-recursive functions immediately\n-    discard those terms.</p>\n-\n-    <p>That used to be true before R7B. In R7B, the compiler started\n-    to generate code that overwrites references to terms that will never\n-    be used with an empty list, so that the garbage collector would not\n-    keep dead values any longer than necessary.</p>\n-\n-    <p>Even after that optimization, a tail-recursive function is\n-    still most of the times faster than a body-recursive function. Why?</p>\n-\n-    <p>It has to do with how many words of stack that are used in each\n-    recursive call. In most cases, a recursive function uses more words\n-    on the stack for each recursion than the number of words a tail-recursive\n-    would allocate on the heap. As more memory is used, the garbage\n-    collector is invoked more frequently, and it has more work traversing\n-    the stack.</p>\n-\n-    <p>In R12B and later releases, there is an optimization that\n-    in many cases reduces the number of words used on the stack in\n-    body-recursive calls. A body-recursive list function and a\n-    tail-recursive function that calls <seealso\n-    marker=\"stdlib:lists#reverse/1\">lists:reverse/1</seealso> at\n-    the end will use the same amount of memory.\n-    <c>lists:map/2</c>, <c>lists:filter/2</c>, list comprehensions,\n-    and many other recursive functions now use the same amount of space\n-    as their tail-recursive equivalents.</p>\n-\n-    <p>So, which is faster?\n-    It depends. On Solaris/Sparc, the body-recursive function seems to\n-    be slightly faster, even for lists with a lot of elements. On the x86\n-    architecture, tail-recursion was up to about 30% faster.</p>\n-\n-    <p>So, the choice is now mostly a matter of taste. If you really do need\n-    the utmost speed, you must <em>measure</em>. You can no longer be\n-    sure that the tail-recursive list function always is the fastest.</p>\n+    using a tail-recursive function that builds a list in reverse\n+    followed by a call to <c>lists:reverse/1</c> is faster than\n+    a body-recursive function that builds the list in correct order.</p>\n+\n+    <p>That was true to some extent before R12B. It was even more true\n+    before R7B. Today, not so much. It is generally not possible to\n+    predict whether the tail-recursive or the body-recursive version will\n+    be faster. Therefore, use the version that makes your code cleaner\n+    (hint: it is usually the body-recursive version).</p>","path":"system/doc/efficiency_guide/myths.xml","position":null,"original_position":97,"commit_id":"5b61a8b1b2edfe70f81d54410c22f868dee46165","original_commit_id":"376c9924108a9adba2f97caa50ee91f1d5b44224","user":{"login":"bjorng","id":74840,"avatar_url":"https://avatars.githubusercontent.com/u/74840?v=3","gravatar_id":"","url":"https://api.github.com/users/bjorng","html_url":"https://github.com/bjorng","followers_url":"https://api.github.com/users/bjorng/followers","following_url":"https://api.github.com/users/bjorng/following{/other_user}","gists_url":"https://api.github.com/users/bjorng/gists{/gist_id}","starred_url":"https://api.github.com/users/bjorng/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bjorng/subscriptions","organizations_url":"https://api.github.com/users/bjorng/orgs","repos_url":"https://api.github.com/users/bjorng/repos","events_url":"https://api.github.com/users/bjorng/events{/privacy}","received_events_url":"https://api.github.com/users/bjorng/received_events","type":"User","site_admin":false},"body":"> Aren't body recursive functions more expensive in memory, and therefore not ideal when you are going to loop a large number of times?\r\n\r\nNo, they are not more expensive in memory (any longer). I have pushed an update to mention that.","created_at":"2016-12-13T14:03:28Z","updated_at":"2016-12-13T14:03:28Z","html_url":"https://github.com/erlang/otp/pull/1280#discussion_r92173544","pull_request_url":"https://api.github.com/repos/erlang/otp/pulls/1280","_links":{"self":{"href":"https://api.github.com/repos/erlang/otp/pulls/comments/92173544"},"html":{"href":"https://github.com/erlang/otp/pull/1280#discussion_r92173544"},"pull_request":{"href":"https://api.github.com/repos/erlang/otp/pulls/1280"}}},"pull_request":{"url":"https://api.github.com/repos/erlang/otp/pulls/1280","id":97750154,"html_url":"https://github.com/erlang/otp/pull/1280","diff_url":"https://github.com/erlang/otp/pull/1280.diff","patch_url":"https://github.com/erlang/otp/pull/1280.patch","issue_url":"https://api.github.com/repos/erlang/otp/issues/1280","number":1280,"state":"open","locked":false,"title":"Update the myths in the Efficiency Guide for OTP 20","user":{"login":"bjorng","id":74840,"avatar_url":"https://avatars.githubusercontent.com/u/74840?v=3","gravatar_id":"","url":"https://api.github.com/users/bjorng","html_url":"https://github.com/bjorng","followers_url":"https://api.github.com/users/bjorng/followers","following_url":"https://api.github.com/users/bjorng/following{/other_user}","gists_url":"https://api.github.com/users/bjorng/gists{/gist_id}","starred_url":"https://api.github.com/users/bjorng/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bjorng/subscriptions","organizations_url":"https://api.github.com/users/bjorng/orgs","repos_url":"https://api.github.com/users/bjorng/repos","events_url":"https://api.github.com/users/bjorng/events{/privacy}","received_events_url":"https://api.github.com/users/bjorng/received_events","type":"User","site_admin":false},"body":"I originally started to do those updates for OTP 19, but didn't have time to finish them.\r\n","created_at":"2016-12-13T13:25:01Z","updated_at":"2016-12-13T14:03:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a0a1fa3d74cb77cc63442145480ee7cf3568493c","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/erlang/otp/pulls/1280/commits","review_comments_url":"https://api.github.com/repos/erlang/otp/pulls/1280/comments","review_comment_url":"https://api.github.com/repos/erlang/otp/pulls/comments{/number}","comments_url":"https://api.github.com/repos/erlang/otp/issues/1280/comments","statuses_url":"https://api.github.com/repos/erlang/otp/statuses/5b61a8b1b2edfe70f81d54410c22f868dee46165","head":{"label":"bjorng:bjorn/effiency-guide-myths/OTP-13652","ref":"bjorn/effiency-guide-myths/OTP-13652","sha":"5b61a8b1b2edfe70f81d54410c22f868dee46165","user":{"login":"bjorng","id":74840,"avatar_url":"https://avatars.githubusercontent.com/u/74840?v=3","gravatar_id":"","url":"https://api.github.com/users/bjorng","html_url":"https://github.com/bjorng","followers_url":"https://api.github.com/users/bjorng/followers","following_url":"https://api.github.com/users/bjorng/following{/other_user}","gists_url":"https://api.github.com/users/bjorng/gists{/gist_id}","starred_url":"https://api.github.com/users/bjorng/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bjorng/subscriptions","organizations_url":"https://api.github.com/users/bjorng/orgs","repos_url":"https://api.github.com/users/bjorng/repos","events_url":"https://api.github.com/users/bjorng/events{/privacy}","received_events_url":"https://api.github.com/users/bjorng/received_events","type":"User","site_admin":false},"repo":{"id":385395,"name":"otp","full_name":"bjorng/otp","owner":{"login":"bjorng","id":74840,"avatar_url":"https://avatars.githubusercontent.com/u/74840?v=3","gravatar_id":"","url":"https://api.github.com/users/bjorng","html_url":"https://github.com/bjorng","followers_url":"https://api.github.com/users/bjorng/followers","following_url":"https://api.github.com/users/bjorng/following{/other_user}","gists_url":"https://api.github.com/users/bjorng/gists{/gist_id}","starred_url":"https://api.github.com/users/bjorng/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bjorng/subscriptions","organizations_url":"https://api.github.com/users/bjorng/orgs","repos_url":"https://api.github.com/users/bjorng/repos","events_url":"https://api.github.com/users/bjorng/events{/privacy}","received_events_url":"https://api.github.com/users/bjorng/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bjorng/otp","description":"Erlang/OTP","fork":true,"url":"https://api.github.com/repos/bjorng/otp","forks_url":"https://api.github.com/repos/bjorng/otp/forks","keys_url":"https://api.github.com/repos/bjorng/otp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bjorng/otp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bjorng/otp/teams","hooks_url":"https://api.github.com/repos/bjorng/otp/hooks","issue_events_url":"https://api.github.com/repos/bjorng/otp/issues/events{/number}","events_url":"https://api.github.com/repos/bjorng/otp/events","assignees_url":"https://api.github.com/repos/bjorng/otp/assignees{/user}","branches_url":"https://api.github.com/repos/bjorng/otp/branches{/branch}","tags_url":"https://api.github.com/repos/bjorng/otp/tags","blobs_url":"https://api.github.com/repos/bjorng/otp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bjorng/otp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bjorng/otp/git/refs{/sha}","trees_url":"https://api.github.com/repos/bjorng/otp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bjorng/otp/statuses/{sha}","languages_url":"https://api.github.com/repos/bjorng/otp/languages","stargazers_url":"https://api.github.com/repos/bjorng/otp/stargazers","contributors_url":"https://api.github.com/repos/bjorng/otp/contributors","subscribers_url":"https://api.github.com/repos/bjorng/otp/subscribers","subscription_url":"https://api.github.com/repos/bjorng/otp/subscription","commits_url":"https://api.github.com/repos/bjorng/otp/commits{/sha}","git_commits_url":"https://api.github.com/repos/bjorng/otp/git/commits{/sha}","comments_url":"https://api.github.com/repos/bjorng/otp/comments{/number}","issue_comment_url":"https://api.github.com/repos/bjorng/otp/issues/comments{/number}","contents_url":"https://api.github.com/repos/bjorng/otp/contents/{+path}","compare_url":"https://api.github.com/repos/bjorng/otp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bjorng/otp/merges","archive_url":"https://api.github.com/repos/bjorng/otp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bjorng/otp/downloads","issues_url":"https://api.github.com/repos/bjorng/otp/issues{/number}","pulls_url":"https://api.github.com/repos/bjorng/otp/pulls{/number}","milestones_url":"https://api.github.com/repos/bjorng/otp/milestones{/number}","notifications_url":"https://api.github.com/repos/bjorng/otp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bjorng/otp/labels{/name}","releases_url":"https://api.github.com/repos/bjorng/otp/releases{/id}","deployments_url":"https://api.github.com/repos/bjorng/otp/deployments","created_at":"2009-11-25T16:02:48Z","updated_at":"2014-10-27T15:16:20Z","pushed_at":"2016-12-13T14:01:43Z","git_url":"git://github.com/bjorng/otp.git","ssh_url":"git@github.com:bjorng/otp.git","clone_url":"https://github.com/bjorng/otp.git","svn_url":"https://github.com/bjorng/otp","homepage":"http://erlang.org","size":177558,"stargazers_count":5,"watchers_count":5,"language":"Erlang","has_issues":false,"has_downloads":false,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":5,"default_branch":"master"}},"base":{"label":"erlang:master","ref":"master","sha":"e1cdd3732f5ff447195625620b78883c2f22fb65","user":{"login":"erlang","id":153393,"avatar_url":"https://avatars.githubusercontent.com/u/153393?v=3","gravatar_id":"","url":"https://api.github.com/users/erlang","html_url":"https://github.com/erlang","followers_url":"https://api.github.com/users/erlang/followers","following_url":"https://api.github.com/users/erlang/following{/other_user}","gists_url":"https://api.github.com/users/erlang/gists{/gist_id}","starred_url":"https://api.github.com/users/erlang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erlang/subscriptions","organizations_url":"https://api.github.com/users/erlang/orgs","repos_url":"https://api.github.com/users/erlang/repos","events_url":"https://api.github.com/users/erlang/events{/privacy}","received_events_url":"https://api.github.com/users/erlang/received_events","type":"Organization","site_admin":false},"repo":{"id":374927,"name":"otp","full_name":"erlang/otp","owner":{"login":"erlang","id":153393,"avatar_url":"https://avatars.githubusercontent.com/u/153393?v=3","gravatar_id":"","url":"https://api.github.com/users/erlang","html_url":"https://github.com/erlang","followers_url":"https://api.github.com/users/erlang/followers","following_url":"https://api.github.com/users/erlang/following{/other_user}","gists_url":"https://api.github.com/users/erlang/gists{/gist_id}","starred_url":"https://api.github.com/users/erlang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erlang/subscriptions","organizations_url":"https://api.github.com/users/erlang/orgs","repos_url":"https://api.github.com/users/erlang/repos","events_url":"https://api.github.com/users/erlang/events{/privacy}","received_events_url":"https://api.github.com/users/erlang/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/erlang/otp","description":"Erlang/OTP","fork":false,"url":"https://api.github.com/repos/erlang/otp","forks_url":"https://api.github.com/repos/erlang/otp/forks","keys_url":"https://api.github.com/repos/erlang/otp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/erlang/otp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/erlang/otp/teams","hooks_url":"https://api.github.com/repos/erlang/otp/hooks","issue_events_url":"https://api.github.com/repos/erlang/otp/issues/events{/number}","events_url":"https://api.github.com/repos/erlang/otp/events","assignees_url":"https://api.github.com/repos/erlang/otp/assignees{/user}","branches_url":"https://api.github.com/repos/erlang/otp/branches{/branch}","tags_url":"https://api.github.com/repos/erlang/otp/tags","blobs_url":"https://api.github.com/repos/erlang/otp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/erlang/otp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/erlang/otp/git/refs{/sha}","trees_url":"https://api.github.com/repos/erlang/otp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/erlang/otp/statuses/{sha}","languages_url":"https://api.github.com/repos/erlang/otp/languages","stargazers_url":"https://api.github.com/repos/erlang/otp/stargazers","contributors_url":"https://api.github.com/repos/erlang/otp/contributors","subscribers_url":"https://api.github.com/repos/erlang/otp/subscribers","subscription_url":"https://api.github.com/repos/erlang/otp/subscription","commits_url":"https://api.github.com/repos/erlang/otp/commits{/sha}","git_commits_url":"https://api.github.com/repos/erlang/otp/git/commits{/sha}","comments_url":"https://api.github.com/repos/erlang/otp/comments{/number}","issue_comment_url":"https://api.github.com/repos/erlang/otp/issues/comments{/number}","contents_url":"https://api.github.com/repos/erlang/otp/contents/{+path}","compare_url":"https://api.github.com/repos/erlang/otp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/erlang/otp/merges","archive_url":"https://api.github.com/repos/erlang/otp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/erlang/otp/downloads","issues_url":"https://api.github.com/repos/erlang/otp/issues{/number}","pulls_url":"https://api.github.com/repos/erlang/otp/pulls{/number}","milestones_url":"https://api.github.com/repos/erlang/otp/milestones{/number}","notifications_url":"https://api.github.com/repos/erlang/otp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/erlang/otp/labels{/name}","releases_url":"https://api.github.com/repos/erlang/otp/releases{/id}","deployments_url":"https://api.github.com/repos/erlang/otp/deployments","created_at":"2009-11-16T17:17:57Z","updated_at":"2016-12-13T11:35:09Z","pushed_at":"2016-12-13T14:01:43Z","git_url":"git://github.com/erlang/otp.git","ssh_url":"git@github.com:erlang/otp.git","clone_url":"https://github.com/erlang/otp.git","svn_url":"https://github.com/erlang/otp","homepage":"http://erlang.org","size":178282,"stargazers_count":5123,"watchers_count":5123,"language":"Erlang","has_issues":false,"has_downloads":false,"has_wiki":true,"has_pages":true,"forks_count":1460,"mirror_url":null,"open_issues_count":29,"forks":1460,"open_issues":29,"watchers":5123,"default_branch":"maint"}},"_links":{"self":{"href":"https://api.github.com/repos/erlang/otp/pulls/1280"},"html":{"href":"https://github.com/erlang/otp/pull/1280"},"issue":{"href":"https://api.github.com/repos/erlang/otp/issues/1280"},"comments":{"href":"https://api.github.com/repos/erlang/otp/issues/1280/comments"},"review_comments":{"href":"https://api.github.com/repos/erlang/otp/pulls/1280/comments"},"review_comment":{"href":"https://api.github.com/repos/erlang/otp/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/erlang/otp/pulls/1280/commits"},"statuses":{"href":"https://api.github.com/repos/erlang/otp/statuses/5b61a8b1b2edfe70f81d54410c22f868dee46165"}}}}
{"actor":{"display_login":"bjorng"}}