{"action":"created","issue":{"url":"https://api.github.com/repos/Barbosik/MultiOgar/issues/203","repository_url":"https://api.github.com/repos/Barbosik/MultiOgar","labels_url":"https://api.github.com/repos/Barbosik/MultiOgar/issues/203/labels{/name}","comments_url":"https://api.github.com/repos/Barbosik/MultiOgar/issues/203/comments","events_url":"https://api.github.com/repos/Barbosik/MultiOgar/issues/203/events","html_url":"https://github.com/Barbosik/MultiOgar/issues/203","id":165968299,"number":203,"title":"BinaryWriter is actually slower in long run - comparing Buffer, BinaryWriter, ArrayBuffer+DataView and DynamicBuffer perfomance","user":{"login":"Luka967","id":15956695,"avatar_url":"https://avatars.githubusercontent.com/u/15956695?v=3","gravatar_id":"","url":"https://api.github.com/users/Luka967","html_url":"https://github.com/Luka967","followers_url":"https://api.github.com/users/Luka967/followers","following_url":"https://api.github.com/users/Luka967/following{/other_user}","gists_url":"https://api.github.com/users/Luka967/gists{/gist_id}","starred_url":"https://api.github.com/users/Luka967/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Luka967/subscriptions","organizations_url":"https://api.github.com/users/Luka967/orgs","repos_url":"https://api.github.com/users/Luka967/repos","events_url":"https://api.github.com/users/Luka967/events{/privacy}","received_events_url":"https://api.github.com/users/Luka967/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":5,"created_at":"2016-07-17T09:15:07Z","updated_at":"2016-07-17T11:30:21Z","closed_at":null,"body":"So I was bored after making a small representation of buffers called ByteBuffer which ended up extremely slow in perfomance. I came along with an idea to compare all buffers we've made to now, along with the old companions - Buffer, that slow guy ByteBuffer, ArrayBuffer + DataView combo and DynamicBuffer.\r\n\r\nI made a single modification on DynamicBuffer which removes `flush` function, because it was actually useless as `moveTemp` function reads only the necessary byte amount. With the flush function time will exceed 100ms xD\r\n\r\nThe test was to write an unisigned 32-bit integer with value 2147483647, 100 000 times. The specs ain't awesome, it was done on a c9 virtual machine (512 MB ram, ~1GHz processor or even slower), but that's another topic.\r\n\r\nAt my suprise, DynamicBuffer was actually faster than BinaryWriter - sometimes even 10 milliseconds faster!\r\n![ss1](https://cloud.githubusercontent.com/assets/15956695/16899636/3515d820-4c0b-11e6-9d30-978717993f78.png)\r\n\r\nAlso, BinaryWriter uses the most RAM - because it uses functions instead of already calculated bytes.  Buffer predates ArrayBuffer for 4-5 years, cannot write 64-bit values, and has a security flaw.\r\n\r\nNow someone is thinking \"That's all cool, but those are 100 thousand operations, not the usual 20-200!\". Operation number is just an exponent for the effectiveness of a class. More operations equals more precision on who's better.\r\n\r\nThis was just a test out of my boredom and I just wanted to share the results.\r\n\r\nEDIT: I got even more bored and set up testing for buffer creation. Results again unexpected:\r\n![ss2](https://cloud.githubusercontent.com/assets/15956695/16899804/3862cfa0-4c11-11e6-8d28-dddd81aedd7e.png)\r\nDynamicBuffer is 2-3x faster when creating small buffers.\r\n\r\ntl;dr From 5 same tests, approximate speeds are:\r\nBuffer was the best in 3ms\r\nArrayBuffer+DataView was 2nd in 10ms\r\nDynamicBuffer was 3rd in 42ms\r\nBinaryWriter was 4th in 47ms\r\nByteBuffer was the slowest in 300ms"},"comment":{"url":"https://api.github.com/repos/Barbosik/MultiOgar/issues/comments/233177499","html_url":"https://github.com/Barbosik/MultiOgar/issues/203#issuecomment-233177499","issue_url":"https://api.github.com/repos/Barbosik/MultiOgar/issues/203","id":233177499,"user":{"login":"Barbosik","id":19355276,"avatar_url":"https://avatars.githubusercontent.com/u/19355276?v=3","gravatar_id":"","url":"https://api.github.com/users/Barbosik","html_url":"https://github.com/Barbosik","followers_url":"https://api.github.com/users/Barbosik/followers","following_url":"https://api.github.com/users/Barbosik/following{/other_user}","gists_url":"https://api.github.com/users/Barbosik/gists{/gist_id}","starred_url":"https://api.github.com/users/Barbosik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Barbosik/subscriptions","organizations_url":"https://api.github.com/users/Barbosik/orgs","repos_url":"https://api.github.com/users/Barbosik/repos","events_url":"https://api.github.com/users/Barbosik/events{/privacy}","received_events_url":"https://api.github.com/users/Barbosik/received_events","type":"User","site_admin":false},"created_at":"2016-07-17T11:30:21Z","updated_at":"2016-07-17T11:30:21Z","body":"And I think that your test is incorrect. Probably it performs test with no take into account that JIT compiller is smart enough and can just ommit some parts of code which result is not used.\r\n\r\nSo, I just made a small test. And here is result:\r\n```\r\nG:\\GIT\\TestBuffer>node app.js\r\n[INFO ] ===PASS 1===\r\n[INFO ] DynamicBuffer: 7586.255 [ms] (check=16000)\r\n[INFO ] BinaryWriter:  668.871 [ms] (check=16000)\r\n[INFO ] ===PASS 2===\r\n[INFO ] DynamicBuffer: 7982.670 [ms] (check=16000)\r\n[INFO ] BinaryWriter:  657.101 [ms] (check=16000)\r\n[INFO ] ===PASS 3===\r\n[INFO ] DynamicBuffer: 7932.713 [ms] (check=16000)\r\n[INFO ] BinaryWriter:  691.305 [ms] (check=16000)\r\n[INFO ] ===PASS 4===\r\n[INFO ] DynamicBuffer: 7929.353 [ms] (check=16000)\r\n[INFO ] BinaryWriter:  659.713 [ms] (check=16000)\r\n[INFO ] ===PASS 5===\r\n[INFO ] DynamicBuffer: 7807.980 [ms] (check=16000)\r\n[INFO ] BinaryWriter:  677.840 [ms] (check=16000)\r\n[DEBUG] process.exit(0)\r\n``` \r\n\r\nAs you can see, DynamicBuffer is 10 times slower than BinaryWriter.\r\nBinaryWriter takes **just 0,7 second** to serialize all data.\r\nDynamicBuffer takes **7,5 seconds** to serialize all data. \r\n\r\nI'm used latest DynamicBuffer source from ogar project (https://github.com/OgarProject/Ogar/commit/0bbddbe5a55f9bb7afbf254e0aacfbcb0a925da0).\r\n\r\nHere is a test source code:\r\n```\r\nfunction getTime(t) {\r\n    return t[0] * 1000 + t[1] / 1000000;\r\n}\r\n\r\nfor (var pass = 1; pass <= 5; pass++) {\r\n    Logger.info(\"===PASS \" + pass + \"===\");\r\n    \r\n    /* DynamicBuffer test */\r\n    var check = 0;\r\n    var t1 = process.hrtime();\r\n    for (var i = 0; i < 1000; i++) {\r\n        var writer = new DynamicBuffer(true);\r\n        \r\n        // cell update simulation\r\n        writer.setUint8(16);\r\n        for (var j = 0; j < 1000; j++) {\r\n            writer.setUint32(0);    // ID\r\n            writer.setInt32(0);     // X\r\n            writer.setInt32(0);     // Y\r\n            writer.setUint16(0);    // Size\r\n            writer.setUint8(0);     // Flags\r\n            writer.setUint8(0);     // r\r\n            writer.setUint8(0);     // g\r\n            writer.setUint8(0);     // b\r\n        }\r\n        var result = new Uint8Array(writer.build());\r\n        // we create Uint8Array (because it anyway will be performed before pass the data to WebSocket) \r\n        // So, we take it into account\r\n        result = new Uint8Array(result);\r\n        // utilize result to prevent JIT optimization\r\n        check += result[0];\r\n    }\r\n    var t2 = process.hrtime(t1);\r\n    Logger.info(\"DynamicBuffer: \" + getTime(t2).toFixed(3) + \" [ms] (check=\" + check + \")\");\r\n    \r\n    \r\n    \r\n    /* BinaryWriter test */\r\n    var check = 0;\r\n    var t1 = process.hrtime();\r\n    for (var i = 0; i < 1000; i++) {\r\n        var writer = new BinaryWriter();\r\n        \r\n        // cell update simulation\r\n        writer.writeUInt8(16);\r\n        for (var j = 0; j < 1000; j++) {\r\n            writer.writeUInt32(0);  // ID\r\n            writer.writeInt32(0);   // X\r\n            writer.writeInt32(0);   // Y\r\n            writer.writeUInt16(0);  // Size\r\n            writer.writeUInt8(0);   // Flags\r\n            writer.writeUInt8(0);   // r\r\n            writer.writeUInt8(0);   // g\r\n            writer.writeUInt8(0);   // b\r\n        }\r\n        var result = writer.toBuffer();\r\n        // utilize result to prevent JIT optimization\r\n        check += result[0];\r\n    }\r\n    var t2 = process.hrtime(t1);\r\n    Logger.info(\"BinaryWriter:  \" + getTime(t2).toFixed(3) + \" [ms] (check=\" + check + \")\");\r\n}\r\n```\r\n\r\n\r\n\r\n"}}
{"actor":{"display_login":"Barbosik"}}