Skip to content

thestorefront/poison

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Poison

Travis Hex.pm Hex.pm Gratipay

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 HiPE for native compilation, IO list encoding and single-pass decoding.

Preliminary benchmarking has sometimes put Poison's performance closer to jiffy, and almost always faster than existing Elixir libraries.

Installation

First, add Poison to your mix.exs dependencies:

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

Then, update your dependencies:

$ mix deps.get

Usage

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 -- the 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> IO.puts Poison.Encoder.encode([1, 2, 3], [])
"[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.

Benchmarking

$ mix deps.get
$ MIX_ENV=bench mix compile.protocols
$ MIX_ENV=bench elixir -pa _build/bench/lib/\*/ebin -pa _build/bench/consolidated -S mix bench

License

Poison is released into the public domain (see UNLICENSE). Poison is also optionally available under the ISC License (see LICENSE), meant especially for jurisdictions that do not recognize public domain works.

About

An incredibly fast, pure Elixir JSON library

Resources

License

ISC, Unlicense licenses found

Licenses found

ISC
LICENSE
Unlicense
UNLICENSE

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Elixir 100.0%