Sacrifice readability for compactness and speed
Conversion between decimal and binary
JSON | "2019" | 4 bytes |
bytes | 0000 0111 1110 0011 | 2 bytes |
Bytes are more compact
And faster to decode
JSON | "2019" | parse 4 digits; arithmetic |
bytes | 0000 0111 1110 0011 | just put it in memory |
decodeVec3 : Decoder Vec3
decodeVec3 =
Decode.succeed vec3
|> andMap (Decode.float32 LE)
|> andMap (Decode.float32 LE)
|> andMap (Decode.float32 LE)
type Bytes
Encode.unsignedInt8 : Int -> Encoder
Encode.string : String -> Encoder
Decode.unsignedInt8 : Decoder Int
Decode.string : Int -> Decoder String
Decode.decode : Bytes -> Decoder a -> Maybe a
{
"title": "foo",
"subject": "spam"
}
3 f o o 4 s p a m
03 666f6f 04 7370616d
Field | # of bytes | type |
---|---|---|
titleLength | 1 | uint8 |
title | variable | string |
subjectLength | 1 | uint8 |
subject | variable | string |
type alias Item =
{ title : String
, link : String
, media : String
, dateTaken : Int
, description : String
, published : Int
, author : String
, authorId : String
, tags : List String
}
raw bytes | zipped bytes | |
---|---|---|
JSON | 864 | 437 |
Bytes | 732 | 363 |
15% less | 17% less |
Compaction and speed depend heavily on the specific data
consider the maintenance cost of binary serialization
schema technologies (like protobuf) still run into these issues
data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D
A binary-to-text conversion method
used for
6 bits are enough to store 64 distinct characters
but we can only write/read whole bytes (8 bits)
we will not waste 2 bits per character!
Encode.unsignedInt8 : Int -> Encoder
solution: store 4 digits in 3 bytes
E | 4 | 00 0100 |
V | 21 | 01 0101 |
A | 0 | 00 0000 |
N | 13 | 00 1101 |
use bit shifts to line up
E | 00000000 00000000 00000100 | |
V | 00000000 00000101 01000000 | |
A | 00000000 00000000 00000000 | |
N | 00110100 00000000 00000000 |
then bitwise or to combine
00110100 00000101 01000100 |
You are responsible for performance
learning while writing meaningful code
Folkert de Vries
@folkertdev