Socket
Book a DemoInstallSign in
Socket

msgpack-nodejs

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

msgpack-nodejs

Really fast MessagePack encoder/decoder implemented in Node.js/Typescript

latest
Source
npmnpm
Version
1.3.9
Version published
Weekly downloads
1
-50%
Maintainers
1
Weekly downloads
 
Created
Source

msgpack-nodejs

GitHub Workflow Status Vulnerabilities node-current GitHub top language Lines of code npm bundle size

Yet another javascript/nodejs implementation of MsgPack Spec.
The purpose behind is learning by doing, which focuses on modern tools/techniques of nodejs/typescript ecosystem.

Contents

Usage

npm i msgpack-nodejs
npm test

Example

Please check example.md

API

Options

You can apply options like this

KeytypedefaultDescription
encoder.mapKeyCache.enabledbooleantrueCache map-key or not
encoder.mapKeyCache.sizenumber30How big is the mapKeyCache
encoder.stringCache.enabledbooleantrueCache any string except map-key or not
encoder.stringCache.sizenumber100How big is the stringCache
encoder.byteArray.basenumber1024How many bytes will be allocated for every execution. Setting this would increase performance when handling many big JSON data
decoder.shortStringCache.enabledbooleantrueUse prefix-trie or not
decoder.shortStringCache.lessThannumber10Only cache if string is shorter than this value
decoder.jsUtf8Decode.enabledbooleantrueUse JS utf8-decode or not
decoder.jsUtf8Decode.lessThannumber200Only use JS utf8-decode if string is shorter than this value

Project status

Compability

EnvExecutable?
Node.js 18
Node.js 16
Node.js 14
Node.js 12

Limitation

  • Does not support float 32 encoding, because Javascript float is always 64-bit.

TODO

  • Ext tests
  • Map 16/32 tests

Benchmark

By utlizing the great benchmark tool by msgpack-lite, I thought the performance of this project would not be disappointing.

Runs on node.js 16 & laptop with R5-5625U.

operationopmsop/s
buf = Buffer(JSON.stringify(obj));10212005000204240
obj = JSON.parse(buf);12795005000255900
buf = require("msgpack-lite").encode(obj);6858005000137160
obj = require("msgpack-lite").decode(buf);389800500177944
buf = Buffer(require("msgpack.codec").msgpack.pack(obj));7136005000142720
obj = require("msgpack.codec").msgpack.unpack(buf);401300500180243
buf = require("msgpack-js-v5").encode(obj);284400500056880
obj = require("msgpack-js-v5").decode(buf);5446005000108920
buf = require("msgpack-js").encode(obj);277100500155408
obj = require("msgpack-js").decode(buf);5598005000111960
buf = require("msgpack5")().encode(obj);147700500129534
obj = require("msgpack5")().decode(buf);239500500047900
buf = require("notepack").encode(obj);10415005000208300
obj = require("notepack").decode(buf);6713005000134260
obj = require("msgpack-unpack").decode(buf);163400500132673
buf = require("msgpack-nodejs").encode(obj); (Run in sequence)11489005000229780
obj = require("msgpack-nodejs").decode(buf); (Run in sequence)7775005000155500
buf = require("msgpack-nodejs").encode(obj); (Run exclusively)13219005000264380
obj = require("msgpack-nodejs").decode(buf); (Run exclusively)8054005000161080

Implementation detail

Encode

Encoder uses a recursive function match() to match JSON structure (primitive value, object, array or nested), and pushes anything encoded into ByteArray that responsible for allocating buffer. Encoded string will be written in StringBuffer first and cached in LruCache.

Decode

Decoder uses parseBuffer() to read every value out, and push them into StructBuilder to rebuild whole JSON object. For string less than 200 bytes, use pure JS utf8Decode(), then cache in prefix trie.

Optimization strategies:

Cache
  • To improve encoding performance, LruCache was used for caching encoded string and its header.
  • To improve decoding peformance, prefix trie was deployed for Uint8Array caching.
  • To avoid evicting, map-key caching and string caching were separated.
ArrayBuffer / TypedArray
  • To efficiently allocate new buffer, every ByteArray begins with small buffer (1K). 2
  • To efficiently handle unpredictable large JSON, ByteArray allocates exponentially.
  • To avoid overhead on writing, ByteArray uses DataView calls as much as possible.
Node.js
  • To maximize performance of array, use pre-allocated array. 3
  • To maximize performance of string encoding, string are encoded in StringBuffer with encodeInto() to prevent unnecessary copying. Then these encoded content will be referenced by subarray() for writing and caching. 4
  • To avoid overhead of TextDecoder(), decode UTF-8 bytes with pure JS when less than 200 bytes. 3
  • To avoid GC overhead in decoder, every parsed typed value will be passed into builder.insertValue() directly. 5
  • To avoid syntax penalty of private class fields under node.js 18, use TypeScript's syntax instead.

Lessons learned

  • Javascript
    • The difference between ArrayBuffer, TypedArray and the node.js API Buffer 6
    • BigInt operators 7
    • left shift and right shift 8 9
    • Private class features 10
    • Pre-allocated array 3
    • UTF-8 encoding/decoding 11
    • Node.js transform stream 12
  • Node.js
    • Profiler 13
  • Typescript
    • Testing - ts-jest 14
    • Linter - typescript-eslint & lint-staged 15
    • Packaging for ESModule & CommonJS 16
  • CI & CD
    • Github Actions 17

Footnotes

Keywords

msgpack

FAQs

Package last updated on 16 Jan 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts