pck

Binary data serialization format


Keywords
pck, binary, serialize, binary-format, javascript, serialization
License
MIT
Install
npm install pck@0.0.1

Documentation

PCK is a binary format and a set of tools specifically designed for generating efficient deserializers in javascript.

Features

  • Binary format
  • Compact storage size
  • Javascript as a language to describe schemas
  • Efficient and compact deserialization and serialization in javascript

Supported Programming Languages

Packages

  • pck Core data structures and helper functions for generating schemas.
  • pck-emit-js Emitter for Javascript/TypeScript (Browser/Node).
  • pck-emit-go Emitter for Go.
  • pck-browser Helper utilities for Javascript (Browser).
  • pck-node Helper utilities for Javascript (Node).

Benchmarks

pck-browser is optimized towards fast deserialization performance and compact seralization functions. It is possible to generate way much faster serializers, but it would require generating more code and in most situations it is isn't worth it.

pck-node works in the same way as pck-browser, but Node.js implementation doesn't need to be super compact, so in the future, serialization functions will be optimized towards serialization performance.

Basic Data

Basic benchmarks that serialize and deserialize simple data structure that doesn't contain any strings:

const DATA = {
  health: 100,
  jumping: true,
  position: { x: 10, y: 20 },
  attributes: { str: 100, agi: 50, int: 10 },
};

Schema

const Position = schema(ivar("x"), ivar("y"));
const Attributes = schema(u8("str"), u8("agi"), u8("int"));
const Player = schema(
  ivar("health"),
  bool("jumping"),
  ref("position", Position),
  ref("attributes", Attributes),
);

Storage Size

  • PCK: 8 bytes
  • JSON: 99 bytes

Node v8.8.0 (i5 4570k, Linux)

pck:encode x 3,424,757 ops/sec ±0.96% (94 runs sampled)
pck:decode x 19,974,290 ops/sec ±0.22% (96 runs sampled)
json:encode x 508,511 ops/sec ±1.45% (84 runs sampled)
json:decode x 589,417 ops/sec ±0.27% (96 runs sampled)

Browser (iPad 2017, iOS 11.0.3)

pck:encode x 2,467,280 ops/sec ±4.99% (34 runs sampled)
pck:decode x 27,437,271 ops/sec ±0.78% (64 runs sampled)
json:encode x 626,667 ops/sec ±1.26% (61 runs sampled)
json:decode x 617,130 ops/sec ±0.27% (44 runs sampled)

Browser (Nexus 5, Chrome 61)

pck:encode x 514,284 ops/sec ±5.64% (52 runs sampled)
pck:decode x 1,529,939 ops/sec ±4.71% (49 runs sampled)
json:encode x 127,017 ops/sec ±3.10% (51 runs sampled)
json:decode x 132,055 ops/sec ±0.71% (55 runs sampled)

Go 1.9 (i5 4570k, Linux)

BenchmarkPckEncode-4    	200000000	        65.9 ns/op
BenchmarkPckDecode-4    	200000000	        92.6 ns/op
BenchmarkJsonEncode-4   	10000000	      1380 ns/op
BenchmarkJsonDecode-4   	 3000000	      4624 ns/op

HackerNews Data

This benchmark serializes and deserializes response from HackerNews top stories API.

Schema

const Item = schema(
  utf8("by"),
  uvar("descendants"),
  uvar("id"),
  omitEmpty(omitNull(array("kids", UVAR))),
  uvar("score"),
  u32("time"),
  utf8("title"),
  omitEmpty(utf8("url")),
);

const TopStories = schema(
  array("items", REF(Item)),
);

Storage Size

  • PCK: 94815 bytes
  • JSON: 185885 bytes

Node v8.8.0 (i5 4570k, Linux)

pck:encode x 970 ops/sec ±2.41% (91 runs sampled)
pck:decode x 2,265 ops/sec ±0.67% (94 runs sampled)
json:encode x 1,468 ops/sec ±0.21% (94 runs sampled)
json:decode x 516 ops/sec ±2.86% (82 runs sampled)

Browser (iPad 2017, iOS 11.0.3)

pck:encode x 441 ops/sec ±1.00% (63 runs sampled)
pck:decode x 1,176 ops/sec ±0.50% (62 runs sampled)
json:encode x 941 ops/sec ±0.44% (62 runs sampled)
json:decode x 587 ops/sec ±0.25% (63 runs sampled)

Browser (Nexus 5, Chrome 61)

pck:encode x 102 ops/sec ±6.51% (45 runs sampled)
pck:decode x 511 ops/sec ±2.95% (54 runs sampled)
json:encode x 238 ops/sec ±3.76% (51 runs sampled)
json:decode x 71 ops/sec ±7.94% (44 runs sampled)

Go 1.9 (i5 4570k, Linux)

BenchmarkPckEncode-4    	  100000	    197485 ns/op
BenchmarkPckDecode-4    	   50000	    308749 ns/op
BenchmarkJsonEncode-4   	   10000	   1292727 ns/op
BenchmarkJsonDecode-4   	    3000	   4856830 ns/op

Data Types

Type Storage Size Description
Bool 1 bit (bit store) Boolean
I8 1 byte Int8
U8 1 byte Uint8
I16 2 bytes Int16
U16 2 bytes Uint16
I32 4 bytes Int32
U32 4 bytes Uint32
F32 4 bytes Float32
F64 8 bytes Float64
IVAR 1-5 bytes Variadic Int32 (ZigZag encoding)
UVAR 1-5 bytes Variadic Uint32
UTF8 1-5+N bytes UTF8 String
ASCII 1-5+N bytes ASCII String
BYTES 1-5+N bytes Byte Array
ARRAY 1-5+N bytes Array
MAP(K,V) 1-5+(NK+NV) bytes Map
ASCII(N) N bytes Fixed ASCII String
BYTES(N) N bytes Fixed Byte Array
ARRAY(N) NV bytes Fixed Array
REF(T) size(T) bytes Reference to an Object
UNION(T...) 1-5+size(...T) bytes Tagged Union

Field Flags

Flag Storage Size Description
Optional 1 bit (bit store) OmitNull, OmitEmpty, OmitZero