Upgrade to Pro — share decks privately, control downloads, hide ads and more …

flatbuffers

 flatbuffers

(Almost) every web application passes data from place to place, and a common way to do that is with JSON.

However, JSON has downsides on performance critical paths. Its parsing overhead, even on small payloads, incurs quite a penalty. In mobile devices with weaker hardware this penalty is magnified by jankyness your users might experience. These performance issues can be eliminated using Google’s latest new serialization library - FlatBuffers. We’ll go over some use-cases and see how FlatBuffers let you serialize your data while keeping your application with a sleek 60FPS.

haggai yaniv

August 25, 2016
Tweet

Other Decks in Programming

Transcript

  1. Serialization Serialization is the process of 
 translating data structures

    or object state into a format that can be stored (or transmitted across a 
 network connection) https://en.wikipedia.org/wiki/Serialization
  2. Deserialization The opposite operation, extracting a data structure from a

    series of bytes https://en.wikipedia.org/wiki/Serialization
  3. const person = JSON.parse(response);
 
 
 
 const person =

    {
 firstName: 'Haggai',
 lastName: 'Yaniv',
 age: 30
 };

  4. const person = JSON.parse(response);
 
 console.log(person.firstName) // 'Haggai'
 console.log(person.lastName) //

    'Yaniv'
 console.log(person.age) // 30 const person = {
 firstName: 'Haggai',
 lastName: 'Yaniv',
 age: 30
 };

  5. Serialisation has it's toll Converting a JSON into JavaScript loads

    both the CPU and the memory The impact might be crucial 
 when the device is mobile!
  6. • Started in 2015 as a project by 
 “Fun

    Propulsion Labs” - A Google group dedicated to Android Tools • Originally was oriented for game 
 development on Android • Today being supported for 
 9 programming languages The answer
  7. 1400 0000 0000 0e00 1000 0800 0c00 0600 0000 0000

    0e00 0000 0000 1e00 1400 0000 0400 0000 0500 0000 5961 6e69 7600 0000 0600 0000 4861 6767 6169 0000
  8. 
 namespace Demo.Person;
 
 table Person {
 firstName:string;
 lastName:string;
 age:short;


    }
 
 root_type Person; Note: this is not a JavaScript File person.idl
  9. Now let it generate our getter and setter access code

    ./flatc --js -o ./output ./sample/person.idl
  10. // getters
 Demo.Person.prototype.firstName = function() { ...}
 Demo.Person.prototype.lastName = function()

    { ...}
 Demo.Person.prototype.age = function() { ...}
 
 // setters
 Demo.Person.addFirstName = function() { ...}
 Demo.Person.addLastName = function() { ...}
 Demo.Person.addAge = function() { ...}
 
 // init methods
 Demo.Person.startPerson = function() { ...}
 Demo.Person.endPerson = function() { ...}
 
 // extract the person from the received data
 Demo.Person.getRootAsPerson = function(buff) { ...} We'll get a file called 'person_generated.js' with the following methods
  11. // this is how we used work
 function getResponse(response) {


    const person = JSON.parse(response);
 console.log(person.firstName); // 'haggai'
 console.log(person.lastName); // 'yaniv'
 console.log(person.age); // 30
 
 } Reminder
  12. const Demo = require('./person_generated.js').Demo;
 
 
 // now the new

    way
 function getPerson(response) {
 // Get access to the root:
 const person = Demo.Person.getRootAsPerson(response);
 
 console.log(person.firstName()); // 'haggai'
 console.log(person.lastName()); // 'yaniv'
 console.log(person.age()); // 30
 
 } The new way is:
  13. Vtable (shared between other Person instances) firstNameOffset lastNameOffset age 4

    5 6 Person Instance vptr firstName reference lastName refernce 30[short] firstName h a g g a i
  14. 
 
 namespace Demo.Person;
 
 
 
 
 table Person

    {
 firstName:string;
 lastName:string;
 age:short;
 
 
 }
 
 
 
 
 
 
 
 
 root_type Person;
  15. 
 
 namespace Demo.Person;
 
 
 
 
 table Person

    {
 firstName:string;
 lastName:string;
 age:short;
 
 
 }
 
 
 
 
 
 
 
 
 root_type Person; 
 
 
 
 // NEW FIELD
 enum Department:byte { RnD = 0, Product, Finance = 2 }
 
 
 
 
 
 company:Company; // NEW FIELD
 department:Department = RnD; // NEW FIELD
 
 
 // NEW TABLE
 table Company {
 companyName:string;
 companyStreetName:string;
 streetNumber:short;
 }
 

  16. Person.Company.prototype.company = function() {...}
 Person.Company.prototype.companyName = function() {...}
 Person.Company.prototype.companyStreetName =

    function() {...}
 Person.Company.prototype.streetNumber = function() {...} Additional methods at 'person_generated.js'
  17. • To gain the full benefits you must use generated

    code getters • Not very human readable • Not ideal for mutating objects • Eco system in JS has a way to go Caveats
  18. Main Benefits Cross platform code with no dependencies No need

    to parse/stringify Efficient in memory - no extra memory beside the data itself Enables efficient random access memory
  19. JSON representation of the relations Story: { Actor: John, Feedback:

    { Likers:[Mary], Comments: [ { Author:Mark Text:... } ] } Attachment: { Pictures: [ { PictureUr:... },
  20. Parsing 20kb JSON object took 35ms In order to achieve

    sleek 60fps parsing needs to take less than 16.7ms
  21. After switching to FlatBuffers • Time to load each story

    reduced from 35ms to 4ms
 • Transient memory allocations are 
 reduced by 75%.
  22. Let's wrap it up • FlatBuffer has impressive performance abilities.

    • But remember, use it wisely :) • Major factor with limited resource devices
  23. Learn More • See the official FlatBuffers page at: https://google.github.io/flatbuffers/

    • Sample code from our talk can be found here: https://github.com/yhaggai/flatbuffers-sample • Facebook's tech blog about FlatBuffers