{"action":"created","issue":{"url":"https://api.github.com/repos/github/bert/issues/14","repository_url":"https://api.github.com/repos/github/bert","labels_url":"https://api.github.com/repos/github/bert/issues/14/labels{/name}","comments_url":"https://api.github.com/repos/github/bert/issues/14/comments","events_url":"https://api.github.com/repos/github/bert/issues/14/events","html_url":"https://github.com/github/bert/pull/14","id":368803289,"node_id":"MDExOlB1bGxSZXF1ZXN0MjIxODk1NjEz","number":14,"title":"Use shared strings to decrease allocated bytes.","user":{"login":"tenderlove","id":3124,"node_id":"MDQ6VXNlcjMxMjQ=","avatar_url":"https://avatars1.githubusercontent.com/u/3124?v=4","gravatar_id":"","url":"https://api.github.com/users/tenderlove","html_url":"https://github.com/tenderlove","followers_url":"https://api.github.com/users/tenderlove/followers","following_url":"https://api.github.com/users/tenderlove/following{/other_user}","gists_url":"https://api.github.com/users/tenderlove/gists{/gist_id}","starred_url":"https://api.github.com/users/tenderlove/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tenderlove/subscriptions","organizations_url":"https://api.github.com/users/tenderlove/orgs","repos_url":"https://api.github.com/users/tenderlove/repos","events_url":"https://api.github.com/users/tenderlove/events{/privacy}","received_events_url":"https://api.github.com/users/tenderlove/received_events","type":"User","site_admin":true},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2018-10-10T18:51:42Z","updated_at":"2018-10-10T19:19:00Z","closed_at":null,"author_association":"COLLABORATOR","pull_request":{"url":"https://api.github.com/repos/github/bert/pulls/14","html_url":"https://github.com/github/bert/pull/14","diff_url":"https://github.com/github/bert/pull/14.diff","patch_url":"https://github.com/github/bert/pull/14.patch"},"body":"This commit uses string byteslice rather than rb_str_new so that we can\r\ntake advantage of Ruby's shared string optimizations.  Since we are\r\nslicing all the way to the end of a buffer, we can use a trick which\r\nlets us share byte buffers between string objects.\r\n\r\nHere is the benchmark code:\r\n\r\n```ruby\r\nrequire 'bert'\r\nrequire 'allocation_tracer'\r\n\r\nzeroes = \"0\" * (1024*1024*50)\r\n\r\nBERT::Encode.version = :v4\r\n\r\nbuf = BERT.encode zeroes\r\n\r\nObjectSpace::AllocationTracer.setup(%i{path line type})\r\n\r\nresult = ObjectSpace::AllocationTracer.trace do\r\n  5.times { BERT.decode(buf) }\r\nend\r\n\r\np [:file, :line, :type, :bytes]\r\nresult.each do |(file, line, type), info|\r\n  p [file, line, type, info.last]\r\nend\r\n```\r\n\r\nHere is the output before the change:\r\n\r\n```\r\n[aaron@TC-265 bert (slice-instead-of-dup)]$ be ruby -I lib:~/git/allocation_tracer/lib test.rb\r\n[:file, :line, :type, :bytes]\r\n[\"/Users/aaron/github/bert/lib/bert/decoder.rb\", 8, :T_STRING, 209715374]\r\n[\"/Users/aaron/github/bert/lib/bert/decoder.rb\", 8, :T_IMEMO, 0]\r\n```\r\n\r\nHere is the output after this patch:\r\n\r\n```\r\n[aaron@TC-265 bert (slice-instead-of-dup)]$ be ruby -I lib:~/git/allocation_tracer/lib test.rb\r\n[:file, :line, :type, :bytes]\r\n[\"/Users/aaron/github/bert/lib/bert/decoder.rb\", 8, :T_STRING, 52428961]\r\n[\"/Users/aaron/github/bert/lib/bert/decoder.rb\", 8, :T_IMEMO, 0]\r\n```\r\n\r\nSince we share string buffers, the decode method allocates much less\r\nmemory."},"comment":{"url":"https://api.github.com/repos/github/bert/issues/comments/428698147","html_url":"https://github.com/github/bert/pull/14#issuecomment-428698147","issue_url":"https://api.github.com/repos/github/bert/issues/14","id":428698147,"node_id":"MDEyOklzc3VlQ29tbWVudDQyODY5ODE0Nw==","user":{"login":"tenderlove","id":3124,"node_id":"MDQ6VXNlcjMxMjQ=","avatar_url":"https://avatars1.githubusercontent.com/u/3124?v=4","gravatar_id":"","url":"https://api.github.com/users/tenderlove","html_url":"https://github.com/tenderlove","followers_url":"https://api.github.com/users/tenderlove/followers","following_url":"https://api.github.com/users/tenderlove/following{/other_user}","gists_url":"https://api.github.com/users/tenderlove/gists{/gist_id}","starred_url":"https://api.github.com/users/tenderlove/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tenderlove/subscriptions","organizations_url":"https://api.github.com/users/tenderlove/orgs","repos_url":"https://api.github.com/users/tenderlove/repos","events_url":"https://api.github.com/users/tenderlove/events{/privacy}","received_events_url":"https://api.github.com/users/tenderlove/received_events","type":"User","site_admin":true},"created_at":"2018-10-10T19:18:59Z","updated_at":"2018-10-10T19:18:59Z","author_association":"COLLABORATOR","body":"I just applied the same optimization on the Ruby side.  Since we usually use Mochilo, I don't actually see a need for us to use the BERT C extension (on the decoding side anyway).  The Ruby code should perform just as well (possibly better because C extensions do not have method caches)."}}
{"actor":{"display_login":"tenderlove"}}