All Projects → devinus → Poison

devinus / Poison

Licence: other
An incredibly fast, pure Elixir JSON library

Programming Languages

elixir
2628 projects
Dockerfile
14818 projects

Projects that are alternatives of or similar to Poison

Dictfier
Python library to convert/serialize class instances(Objects) both flat and nested into a dictionary data structure. It's very useful in converting Python Objects into JSON format
Stars: ✭ 67 (-96.47%)
Mutual labels:  json, json-parser
Simdjson php
simdjson_php bindings for the simdjson project. https://github.com/lemire/simdjson
Stars: ✭ 90 (-95.26%)
Mutual labels:  json, json-parser
Fastjson
Fast JSON parser and validator for Go. No custom structs, no code generation, no reflection
Stars: ✭ 1,164 (-38.67%)
Mutual labels:  json, json-parser
Gjson
Get JSON values quickly - JSON parser for Go
Stars: ✭ 9,453 (+398.05%)
Mutual labels:  json, json-parser
Gitlogg
💾 🧮 🤯 Parse the 'git log' of multiple repos to 'JSON'
Stars: ✭ 102 (-94.63%)
Mutual labels:  json, json-parser
Njson
Unmarshal/Decode nested JSON by JSON Path
Stars: ✭ 61 (-96.79%)
Mutual labels:  json, json-parser
Waargonaut
JSON decoding/encoding/manipulation library.
Stars: ✭ 82 (-95.68%)
Mutual labels:  json, json-parser
Univalue
High performance RAII C++ JSON library and universal value object class
Stars: ✭ 46 (-97.58%)
Mutual labels:  json, json-parser
Simplejson
simplejson is a simple, fast, extensible JSON encoder/decoder for Python
Stars: ✭ 1,372 (-27.71%)
Mutual labels:  json, json-parser
Java
jsoniter (json-iterator) is fast and flexible JSON parser available in Java and Go
Stars: ✭ 1,308 (-31.09%)
Mutual labels:  json, json-parser
Jsmnsol
A JSON parser for solidity
Stars: ✭ 56 (-97.05%)
Mutual labels:  json, json-parser
Spotify Json
Fast and nice to use C++ JSON library.
Stars: ✭ 145 (-92.36%)
Mutual labels:  json, json-parser
Lazyjson
A very fast, very lazy JSON parser for Java.
Stars: ✭ 55 (-97.1%)
Mutual labels:  json, json-parser
Zzzjson
The fastest JSON parser written in pure C
Stars: ✭ 66 (-96.52%)
Mutual labels:  json, json-parser
Gofasion
A lightweight json parsing library for golang.
Stars: ✭ 52 (-97.26%)
Mutual labels:  json, json-parser
Mir Ion
WIP, use libmir/asdf package for now
Stars: ✭ 78 (-95.89%)
Mutual labels:  json, json-parser
Parson
Lightweight JSON library written in C.
Stars: ✭ 965 (-49.16%)
Mutual labels:  json, json-parser
Flatjson
A fast JSON parser (and builder)
Stars: ✭ 39 (-97.95%)
Mutual labels:  json, json-parser
Go
A high-performance 100% compatible drop-in replacement of "encoding/json"
Stars: ✭ 10,248 (+439.94%)
Mutual labels:  json, json-parser
Dynamodb Json
DynamoDB json util to load and dump strings of Dynamodb json format to python object and vise-versa
Stars: ✭ 114 (-93.99%)
Mutual labels:  json, json-parser

Poison

Build Status Coverage Status Hex.pm Version Hex.pm Download Total

Poison is a new JSON library for Elixir focusing on wicked-fast speed without sacrificing simplicity, completeness, or correctness.

Poison takes several approaches to be the fastest JSON library for Elixir.

Poison uses extensive sub binary matching, a hand-rolled parser using several techniques that are known to benefit BeamAsm for JIT compilation, IO list encoding and single-pass decoding.

Poison benchmarks sometimes puts Poison's performance close to jiffy and usually faster than other Erlang/Elixir libraries.

Poison fully conforms to RFC 7159, ECMA 404, and fully passes the JSONTestSuite.

Installation

First, add Poison to your mix.exs dependencies:

def deps do
  [{:poison, "~> 5.0"}]
end

Then, update your dependencies:

$ mix deps.get

Usage

Poison.encode!(%{"age" => 27, "name" => "Devin Torres"})
#=> "{\"name\":\"Devin Torres\",\"age\":27}"

Poison.decode!(~s({"name": "Devin Torres", "age": 27}))
#=> %{"age" => 27, "name" => "Devin Torres"}

defmodule Person do
  @derive [Poison.Encoder]
  defstruct [:name, :age]
end

Poison.encode!(%Person{name: "Devin Torres", age: 27})
#=> "{\"name\":\"Devin Torres\",\"age\":27}"

Poison.decode!(~s({"name": "Devin Torres", "age": 27}), as: %Person{})
#=> %Person{name: "Devin Torres", age: 27}

Poison.decode!(~s({"people": [{"name": "Devin Torres", "age": 27}]}),
  as: %{"people" => [%Person{}]})
#=> %{"people" => [%Person{age: 27, name: "Devin Torres"}]}

Every component of Poison (encoder, decoder, and parser) are all usable on their own without buying into other functionality. For example, if you were interested purely in the speed of parsing JSON without a decoding step, you could simply call Poison.Parser.parse.

Parser

iex> Poison.Parser.parse!(~s({"name": "Devin Torres", "age": 27}), %{})
%{"name" => "Devin Torres", "age" => 27}
iex> Poison.Parser.parse!(~s({"name": "Devin Torres", "age": 27}), %{keys: :atoms!})
%{name: "Devin Torres", age: 27}

Note that keys: :atoms! reuses existing atoms, i.e. if :name was not allocated before the call, you will encounter an argument error message.

You can use the keys: :atoms variant to make sure all atoms are created as needed. However, unless you absolutely know what you're doing, do not do it. Atoms are not garbage-collected, see Erlang Efficiency Guide for more info:

Atoms are not garbage-collected. Once an atom is created, it will never be removed. The emulator will terminate if the limit for the number of atoms (1048576 by default) is reached.

Encoder

iex> Poison.Encoder.encode([1, 2, 3], %{}) |> IO.iodata_to_binary
"[1,2,3]"

Anything implementing the Encoder protocol is expected to return an IO list to be embedded within any other Encoder's implementation and passable to any IO subsystem without conversion.

defimpl Poison.Encoder, for: Person do
  def encode(%{name: name, age: age}, options) do
    Poison.Encoder.BitString.encode("#{name} (#{age})", options)
  end
end

For maximum performance, make sure you @derive [Poison.Encoder] for any struct you plan on encoding.

Encoding only some attributes

When deriving structs for encoding, it is possible to select or exclude specific attributes. This is achieved by deriving Poison.Encoder with the :only or :except options set:

defmodule PersonOnlyName do
  @derive {Poison.Encoder, only: [:name]}
  defstruct [:name, :age]
end

defmodule PersonWithoutName do
  @derive {Poison.Encoder, except: [:name]}
  defstruct [:name, :age]
end

In case both :only and :except keys are defined, the :except option is ignored.

Key Validation

According to RFC 7159 keys in a JSON object should be unique. This is enforced and resolved in different ways in other libraries. In the Ruby JSON library for example, the output generated from encoding a hash with a duplicate key (say one is a string, the other an atom) will include both keys. When parsing JSON of this type, Chromium will override all previous values with the final one.

Poison will generate JSON with duplicate keys if you attempt to encode a map with atom and string keys whose encoded names would clash. If you'd like to ensure that your generated JSON doesn't have this issue, you can pass the strict_keys: true option when encoding. This will force the encoding to fail.

Note: Validating keys can cause a small performance hit.

iex> Poison.encode!(%{:foo => "foo1", "foo" => "foo2"}, strict_keys: true)
** (Poison.EncodeError) duplicate key found: :foo

Benchmarking

$ MIX_ENV=bench mix run bench/run.exs

Current Benchmarks

As of 2021-07-22:

License

Poison is released under the public-domain-equivalent 0BSD license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].