jsonifier 0.1.0.4 → 0.1.0.5
raw patch · 6 files changed
+78/−63 lines, 6 files
Files
- README.md +35/−30
- bench/Main.hs +20/−15
- cbits/json_allocation.c +5/−2
- cbits/json_encoding.c +16/−14
- jsonifier.cabal +1/−1
- library/Jsonifier.hs +1/−1
README.md view
@@ -22,36 +22,41 @@ "buffer-builder" is another library providing an alternative JSON encoder. ```-jsonifier/1kB mean 2.037 μs ( +- 15.93 ns )-jsonifier/6kB mean 12.68 μs ( +- 272.7 ns )-jsonifier/60kB mean 122.7 μs ( +- 3.081 μs )-jsonifier/600kB mean 1.304 ms ( +- 16.41 μs )-jsonifier/6MB mean 20.98 ms ( +- 825.8 μs )-jsonifier/60MB mean 197.1 ms ( +- 14.81 ms )-aeson/1kB mean 6.470 μs ( +- 118.5 ns )-aeson/6kB mean 31.42 μs ( +- 680.3 ns )-aeson/60kB mean 265.0 μs ( +- 5.558 μs )-aeson/600kB mean 3.435 ms ( +- 99.90 μs )-aeson/6MB mean 30.57 ms ( +- 470.7 μs )-aeson/60MB mean 278.5 ms ( +- 6.307 ms )-lazy-aeson/1kB mean 6.419 μs ( +- 183.5 ns )-lazy-aeson/6kB mean 30.72 μs ( +- 501.1 ns )-lazy-aeson/60kB mean 257.0 μs ( +- 4.227 μs )-lazy-aeson/600kB mean 2.533 ms ( +- 61.61 μs )-lazy-aeson/6MB mean 25.08 ms ( +- 263.9 μs )-lazy-aeson/60MB mean 249.5 ms ( +- 1.333 ms )-lazy-aeson-untrimmed-32k/1kB mean 6.952 μs ( +- 427.0 ns )-lazy-aeson-untrimmed-32k/6kB mean 29.68 μs ( +- 656.5 ns )-lazy-aeson-untrimmed-32k/60kB mean 259.8 μs ( +- 4.344 μs )-lazy-aeson-untrimmed-32k/600kB mean 2.521 ms ( +- 21.90 μs )-lazy-aeson-untrimmed-32k/6MB mean 25.25 ms ( +- 295.5 μs )-lazy-aeson-untrimmed-32k/60MB mean 250.8 ms ( +- 3.536 ms )-buffer-builder/1kB mean 5.573 μs ( +- 151.5 ns )-buffer-builder/6kB mean 30.40 μs ( +- 457.2 ns )-buffer-builder/60kB mean 308.9 μs ( +- 4.601 μs )-buffer-builder/600kB mean 3.020 ms ( +- 54.79 μs )-buffer-builder/6MB mean 33.55 ms ( +- 497.8 μs )-buffer-builder/60MB mean 316.1 ms ( +- 3.747 ms )+1kB/jsonifier mean 2.054 μs ( +- 30.83 ns )+1kB/aeson mean 6.456 μs ( +- 126.7 ns )+1kB/lazy-aeson mean 6.338 μs ( +- 169.1 ns )+1kB/lazy-aeson-untrimmed-32k mean 6.905 μs ( +- 280.2 ns )+1kB/buffer-builder mean 5.550 μs ( +- 113.2 ns )++6kB/jsonifier mean 12.80 μs ( +- 196.9 ns )+6kB/aeson mean 31.28 μs ( +- 733.2 ns )+6kB/lazy-aeson mean 30.30 μs ( +- 229.5 ns )+6kB/lazy-aeson-untrimmed-32k mean 29.17 μs ( +- 371.3 ns )+6kB/buffer-builder mean 30.39 μs ( +- 387.2 ns )++60kB/jsonifier mean 122.9 μs ( +- 1.492 μs )+60kB/aeson mean 258.4 μs ( +- 1.000 μs )+60kB/lazy-aeson mean 259.4 μs ( +- 4.494 μs )+60kB/lazy-aeson-untrimmed-32k mean 255.7 μs ( +- 3.239 μs )+60kB/buffer-builder mean 309.0 μs ( +- 3.907 μs )++600kB/jsonifier mean 1.299 ms ( +- 16.44 μs )+600kB/aeson mean 3.389 ms ( +- 106.8 μs )+600kB/lazy-aeson mean 2.520 ms ( +- 45.51 μs )+600kB/lazy-aeson-untrimmed-32k mean 2.509 ms ( +- 30.76 μs )+600kB/buffer-builder mean 3.012 ms ( +- 85.22 μs )++6MB/jsonifier mean 20.91 ms ( +- 821.7 μs )+6MB/aeson mean 30.74 ms ( +- 509.4 μs )+6MB/lazy-aeson mean 24.83 ms ( +- 184.3 μs )+6MB/lazy-aeson-untrimmed-32k mean 24.93 ms ( +- 383.2 μs )+6MB/buffer-builder mean 32.98 ms ( +- 700.1 μs )++60MB/jsonifier mean 194.8 ms ( +- 13.93 ms )+60MB/aeson mean 276.0 ms ( +- 5.194 ms )+60MB/lazy-aeson mean 246.9 ms ( +- 3.122 ms )+60MB/lazy-aeson-untrimmed-32k mean 245.1 ms ( +- 1.050 ms )+60MB/buffer-builder mean 312.0 ms ( +- 4.896 ms ) ``` The benchmark suite is bundled with the package.
bench/Main.hs view
@@ -47,30 +47,35 @@ sample "twitter with 100,000 objects" twitter100000Data let- benchLib :: NFData a => String -> (Model.Result -> a) -> Benchmark- benchLib name encode =++ benchInput :: String -> Model.Result -> Benchmark+ benchInput name input = bgroup name [- bench "1kB" (nf encode twitter1Data)- ,- bench "6kB" (nf encode twitter10Data)+ bench "jsonifier" (nf encodeWithJsonifier input) ,- bench "60kB" (nf encode twitter100Data)+ bench "aeson" (nf encodeWithAeson input) ,- bench "600kB" (nf encode twitter1000Data)+ bench "lazy-aeson" (nf encodeWithLazyAeson input) ,- bench "6MB" (nf encode twitter10000Data)+ bench "lazy-aeson-untrimmed-32k" (nf Main.Aeson.resultToLazyByteStringWithUntrimmedStrategy input) ,- bench "60MB" (nf encode twitter100000Data)+ bench "buffer-builder" (nf BufferBuilder.encodeResult input) ]+ in defaultMain [- benchLib "jsonifier" encodeWithJsonifier,- benchLib "aeson" encodeWithAeson,- benchLib "lazy-aeson" encodeWithLazyAeson,- benchLib "lazy-aeson-untrimmed-32k" Main.Aeson.resultToLazyByteStringWithUntrimmedStrategy,- benchLib "buffer-builder" BufferBuilder.encodeResult+ benchInput "1kB" twitter1Data+ ,+ benchInput "6kB" twitter10Data+ ,+ benchInput "60kB" twitter100Data+ ,+ benchInput "600kB" twitter1000Data+ ,+ benchInput "6MB" twitter10000Data+ ,+ benchInput "60MB" twitter100000Data ]- load :: FilePath -> IO Model.Result load fileName =
cbits/json_allocation.c view
@@ -24,19 +24,22 @@ size_t allocation = 0; while (src_ptr < end_ptr) {- uint16_t w = *src_ptr++;+ uint16_t w = *src_ptr; if (w <= 0x7F) { allocation += allocation_by_septet[w];+ src_ptr += 1; } else if (w <= 0x7FF) { allocation += 2;+ src_ptr += 1; } else if (w < 0xD800 || w > 0xDBFF) { allocation += 3;+ src_ptr += 1; } else {- src_ptr++; allocation += 4;+ src_ptr += 2; } }
cbits/json_encoding.c view
@@ -16,18 +16,20 @@ static const char* digits = "0123456789abcdef"; -#define slash_slash_seq '\\' | '\\' << 8-#define slash_doublequote_seq '\\' | '"' << 8-#define slash_n_seq '\\' | 'n' << 8-#define slash_r_seq '\\' | 'r' << 8-#define slash_t_seq '\\' | 't' << 8-#define slash_u_seq '\\' | 'u' << 8+#define slash_slash_seq_def '\\' | '\\' << 8+#define slash_doublequote_seq_def '\\' | '"' << 8+#define slash_n_seq_def '\\' | 'n' << 8+#define slash_r_seq_def '\\' | 'r' << 8+#define slash_t_seq_def '\\' | 't' << 8+#define slash_u_seq_def '\\' | 'u' << 8 +static const uint16_t slash_u_seq = slash_u_seq_def;+ static const bool pass_through_by_septet[128] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; static const uint16_t two_byte_seq_by_septet[128] =- {0,0,0,0,0,0,0,0,0,slash_t_seq,slash_n_seq,0,0,slash_r_seq,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,slash_doublequote_seq,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,slash_slash_seq};+ {0,0,0,0,0,0,0,0,0,slash_t_seq_def,slash_n_seq_def,0,0,slash_r_seq_def,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,slash_doublequote_seq_def,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,slash_slash_seq_def}; uint8_t* encode_utf16_as_string (@@ -58,19 +60,19 @@ } else { // \u *((uint16_t*) dest) = slash_u_seq;- dest += 2; // hex encoding of 4 nibbles- *dest++ = digits[x >> 12 & 0xF];- *dest++ = digits[x >> 8 & 0xF];- *dest++ = digits[x >> 4 & 0xF];- *dest++ = digits[x & 0xF];+ *(dest + 2) = digits[x >> 12 & 0xF];+ *(dest + 3) = digits[x >> 8 & 0xF];+ *(dest + 4) = digits[x >> 4 & 0xF];+ *(dest + 5) = digits[x & 0xF];+ dest += 6; } } } else if (x <= 0x7FF) {- *dest++ = (x >> 6) | 0xC0;- *dest++ = (x & 0x3f) | 0x80;+ *((uint16_t*) dest) = (x >> 6 | x << 8) & 0x3f3f | 0x80C0;+ dest += 2; } else if (x < 0xD800 || x > 0xDBFF) { *dest++ = (x >> 12) | 0xE0;
jsonifier.cabal view
@@ -1,5 +1,5 @@ name: jsonifier-version: 0.1.0.4+version: 0.1.0.5 synopsis: Fast and simple JSON encoding toolkit description: Minimalistic library for encoding JSON directly to strict bytestring,
library/Jsonifier.hs view
@@ -182,7 +182,7 @@ Poke.pokePtr Poke.closingSquareBracket {-|-JSON Array literal from a foldable over pairs of key to value literal.+JSON Object literal from a foldable over pairs of key to value literal. Don\'t be afraid to use 'fmap' to map the elements of the input datastructure, it will all be optimized away.