{"action":"created","issue":{"url":"https://api.github.com/repos/gopherjs/gopherjs/issues/142","labels_url":"https://api.github.com/repos/gopherjs/gopherjs/issues/142/labels{/name}","comments_url":"https://api.github.com/repos/gopherjs/gopherjs/issues/142/comments","events_url":"https://api.github.com/repos/gopherjs/gopherjs/issues/142/events","html_url":"https://github.com/gopherjs/gopherjs/issues/142","id":53010442,"number":142,"title":"Profiling and optimizing more heavyweight workload.","user":{"login":"shurcooL","id":1924134,"avatar_url":"https://avatars.githubusercontent.com/u/1924134?v=3","gravatar_id":"","url":"https://api.github.com/users/shurcooL","html_url":"https://github.com/shurcooL","followers_url":"https://api.github.com/users/shurcooL/followers","following_url":"https://api.github.com/users/shurcooL/following{/other_user}","gists_url":"https://api.github.com/users/shurcooL/gists{/gist_id}","starred_url":"https://api.github.com/users/shurcooL/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/shurcooL/subscriptions","organizations_url":"https://api.github.com/users/shurcooL/orgs","repos_url":"https://api.github.com/users/shurcooL/repos","events_url":"https://api.github.com/users/shurcooL/events{/privacy}","received_events_url":"https://api.github.com/users/shurcooL/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":11,"created_at":"2014-12-28T21:39:01Z","updated_at":"2015-01-05T07:26:51Z","closed_at":null,"body":"Hi @neelance,\r\n\r\nIn the past I've used GopherJS successfully for some medium-weight workloads, and performance has always been \"good enough not be noticeable or cause any concerns.\"\r\n\r\nRecently I [had a chance](https://twitter.com/shurcooL/status/549105400184700929) to use it for a more significant amount of work, and I'm seeing a quite large discrepancy between native and JS performance.\r\n\r\nNative Go:\r\n\r\n```\r\nRead 1960081 of 1960081 bytes.\r\nDone loading track in: 95.778819ms\r\n```\r\n\r\nGo compiled to JavaScript in browser:\r\n\r\n```\r\nRead 1960081 of 1960081 bytes.\r\nDone loading track in: 27.944s\r\n```\r\n\r\nThe browser execution is around 300x slower. I see the browser tab reaching over 1 GB of RAM while loading the track.\r\n\r\nThe workload can be seen [here](https://github.com/shurcooL/play/blob/e53557dd9c070ce0ec5251108249e5fa85333ae0/95/script.go#L357-L464). It is loading a 2 MB binary file and then parsing it, doing a lot slice allocations and `binary.Read`. The 2 MB binary file (fetched via XHR) is wrapped in a `bytes.NewReader` (and another reader to count length read). Clearly, the Go code was written in the most easy to write and read way, without special considerations for performance.\r\n\r\nI tried to take a CPU profile in browser, and this is what I got:\r\n\r\n![image](https://cloud.githubusercontent.com/assets/1924134/5565027/536e0f0c-8e95-11e4-8a26-dfee01bd407f.png)\r\n\r\nBasically, I wanted to ask for some thoughts:\r\n\r\n1. Does the performance seem reasonable, or it possible there's some single issue/bad practice contributing to a lot of performance degradation?\r\n    - I notice the `newTrack` func is called `$blocking_newTrack`, I wonder if that makes sense.\r\n2. Is the 500 MB - 1.1 GB of RAM usage in the browser table also expected? The native Go binary uses ~50 MB of RAM.\r\n3. Any other hints/tips on other ways I could profile it, other things to try to gain performance. For this task, I would be happy to get to less than 1~5 second track loading time (but that might not be realistic).\r\n4. General thoughts and comments if you have any. :)\r\n\r\nIf you want to reproduce it, it should be straightforward. I've outlined steps in https://github.com/shurcooL/play/commit/e53557dd9c070ce0ec5251108249e5fa85333ae0#commitcomment-9101168. (I use `gopherjs_serve_html` for quicker iterations, but you can just use `gopherjs build script.go` and change `index.html` to use `script.js` instead.)\r\n\r\nOf course, I think the current results are pretty mind blowing, and being able to have it work at all is fantastic! Note that once the track finishes loading, I am able to get 30-60 FPS actually rendering it, so it's quite usable. At the same time, this could be a good benchmark to try various things and see how performance is affected. Hopefully, 30 seconds is just the beginning."},"comment":{"url":"https://api.github.com/repos/gopherjs/gopherjs/issues/comments/68675850","html_url":"https://github.com/gopherjs/gopherjs/issues/142#issuecomment-68675850","issue_url":"https://api.github.com/repos/gopherjs/gopherjs/issues/142","id":68675850,"user":{"login":"shurcooL","id":1924134,"avatar_url":"https://avatars.githubusercontent.com/u/1924134?v=3","gravatar_id":"","url":"https://api.github.com/users/shurcooL","html_url":"https://github.com/shurcooL","followers_url":"https://api.github.com/users/shurcooL/followers","following_url":"https://api.github.com/users/shurcooL/following{/other_user}","gists_url":"https://api.github.com/users/shurcooL/gists{/gist_id}","starred_url":"https://api.github.com/users/shurcooL/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/shurcooL/subscriptions","organizations_url":"https://api.github.com/users/shurcooL/orgs","repos_url":"https://api.github.com/users/shurcooL/repos","events_url":"https://api.github.com/users/shurcooL/events{/privacy}","received_events_url":"https://api.github.com/users/shurcooL/received_events","type":"User","site_admin":false},"created_at":"2015-01-05T07:26:51Z","updated_at":"2015-01-05T07:26:51Z","body":"Just benchmarked the previous 2 versions on iPad too (edited posts above for multiple run numbers), to get a more complete picture, here's a summary:\r\n\r\n```\r\ncomputer: 14s -> 7s -> 3s\r\niPad: 35s -> 20s -> 13s\r\n```\r\n\r\nAmazing job! I'm not seeing any issues so far, just increased performance."}}