Performance
circe aims to be more focused on performance. I'm still experimenting with the right balance, but I'm open to using mutability, inheritance, and all kinds of other horrible things under the hood if they make circe faster (the public API does not and will never expose any of this, though).
My initial benchmarks suggest this is at least kind of working (higher numbers are better):
Benchmark Mode Cnt Score Error Units
DecodingBenchmark.decodeFoosC thrpt 40 3711.680 ± 22.766 ops/s
DecodingBenchmark.decodeFoosA thrpt 40 1519.045 ± 11.373 ops/s
DecodingBenchmark.decodeFoosP thrpt 40 2032.834 ± 27.033 ops/s
DecodingBenchmark.decodeFoosPico thrpt 40 2003.106 ± 10.463 ops/s
DecodingBenchmark.decodeFoosS thrpt 40 7053.699 ± 35.127 ops/s
DecodingBenchmark.decodeIntsC thrpt 40 19101.875 ± 324.123 ops/s
DecodingBenchmark.decodeIntsA thrpt 40 8000.093 ± 215.702 ops/s
DecodingBenchmark.decodeIntsP thrpt 40 18160.031 ± 68.777 ops/s
DecodingBenchmark.decodeIntsPico thrpt 40 11979.085 ± 89.793 ops/s
DecodingBenchmark.decodeIntsS thrpt 40 81279.228 ± 1203.751 ops/s
EncodingBenchmark.encodeFoosC thrpt 40 7353.158 ± 133.633 ops/s
EncodingBenchmark.encodeFoosA thrpt 40 5638.358 ± 30.315 ops/s
EncodingBenchmark.encodeFoosP thrpt 40 2324.075 ± 17.868 ops/s
EncodingBenchmark.encodeFoosPico thrpt 40 5056.317 ± 45.876 ops/s
EncodingBenchmark.encodeFoosS thrpt 40 5307.422 ± 29.666 ops/s
EncodingBenchmark.encodeIntsC thrpt 40 117885.093 ± 2151.059 ops/s
EncodingBenchmark.encodeIntsA thrpt 40 72986.276 ± 1561.295 ops/s
EncodingBenchmark.encodeIntsP thrpt 40 55117.582 ± 650.154 ops/s
EncodingBenchmark.encodeIntsPico thrpt 40 31602.757 ± 351.578 ops/s
EncodingBenchmark.encodeIntsS thrpt 40 40509.667 ± 560.439 ops/s
ParsingBenchmark.parseFoosC thrpt 40 2869.779 ± 61.898 ops/s
ParsingBenchmark.parseFoosA thrpt 40 2615.299 ± 25.881 ops/s
ParsingBenchmark.parseFoosP thrpt 40 1970.493 ± 90.383 ops/s
ParsingBenchmark.parseFoosPico thrpt 40 3113.232 ± 29.081 ops/s
ParsingBenchmark.parseFoosS thrpt 40 3725.056 ± 68.794 ops/s
ParsingBenchmark.parseIntsC thrpt 40 13062.151 ± 209.713 ops/s
ParsingBenchmark.parseIntsA thrpt 40 11066.850 ± 159.308 ops/s
ParsingBenchmark.parseIntsP thrpt 40 18980.265 ± 91.351 ops/s
ParsingBenchmark.parseIntsPico thrpt 40 15184.314 ± 37.808 ops/s
ParsingBenchmark.parseIntsS thrpt 40 15495.935 ± 388.922 ops/s
PrintingBenchmark.printFoosC thrpt 40 4090.218 ± 38.804 ops/s
PrintingBenchmark.printFoosA thrpt 40 2863.570 ± 19.091 ops/s
PrintingBenchmark.printFoosP thrpt 40 9042.816 ± 49.199 ops/s
PrintingBenchmark.printFoosPico thrpt 40 4759.601 ± 20.467 ops/s
PrintingBenchmark.printFoosS thrpt 40 7297.047 ± 28.168 ops/s
PrintingBenchmark.printIntsC thrpt 40 24596.715 ± 66.366 ops/s
PrintingBenchmark.printIntsA thrpt 40 15611.121 ± 140.017 ops/s
PrintingBenchmark.printIntsP thrpt 40 66283.874 ± 731.534 ops/s
PrintingBenchmark.printIntsPico thrpt 40 23703.796 ± 188.186 ops/s
PrintingBenchmark.printIntsS thrpt 40 53015.753 ± 462.472 ops/s
And allocation rates (lower is better):
Benchmark Mode Cnt Score Error Units
DecodingBenchmark.decodeFoosC:gc.alloc.rate.norm thrpt 20 1308424.455 ± 0.881 B/op
DecodingBenchmark.decodeFoosA:gc.alloc.rate.norm thrpt 20 3779097.640 ± 2.456 B/op
DecodingBenchmark.decodeFoosP:gc.alloc.rate.norm thrpt 20 2201336.820 ± 1.588 B/op
DecodingBenchmark.decodeFoosPico:gc.alloc.rate.norm thrpt 20 506696.832 ± 1.608 B/op
DecodingBenchmark.decodeFoosS:gc.alloc.rate.norm thrpt 20 273184.238 ± 0.458 B/op
DecodingBenchmark.decodeIntsC:gc.alloc.rate.norm thrpt 20 291360.090 ± 0.174 B/op
DecodingBenchmark.decodeIntsA:gc.alloc.rate.norm thrpt 20 655448.200 ± 0.387 B/op
DecodingBenchmark.decodeIntsP:gc.alloc.rate.norm thrpt 20 369144.097 ± 0.189 B/op
DecodingBenchmark.decodeIntsPico:gc.alloc.rate.norm thrpt 20 235400.144 ± 0.280 B/op
DecodingBenchmark.decodeIntsS:gc.alloc.rate.norm thrpt 20 38136.021 ± 0.041 B/op
EncodingBenchmark.encodeFoosC:gc.alloc.rate.norm thrpt 20 395272.225 ± 0.433 B/op
EncodingBenchmark.encodeFoosA:gc.alloc.rate.norm thrpt 20 521136.306 ± 0.595 B/op
EncodingBenchmark.encodeFoosP:gc.alloc.rate.norm thrpt 20 1367800.719 ± 7.263 B/op
EncodingBenchmark.encodeFoosPico:gc.alloc.rate.norm thrpt 20 281992.346 ± 0.674 B/op
EncodingBenchmark.encodeFoosS:gc.alloc.rate.norm thrpt 20 377856.318 ± 0.615 B/op
EncodingBenchmark.encodeIntsC:gc.alloc.rate.norm thrpt 20 64160.016 ± 7.129 B/op
EncodingBenchmark.encodeIntsA:gc.alloc.rate.norm thrpt 20 80152.023 ± 0.044 B/op
EncodingBenchmark.encodeIntsP:gc.alloc.rate.norm thrpt 20 71352.030 ± 0.058 B/op
EncodingBenchmark.encodeIntsPico:gc.alloc.rate.norm thrpt 20 58992.057 ± 0.115 B/op
EncodingBenchmark.encodeIntsS:gc.alloc.rate.norm thrpt 20 76176.042 ± 0.081 B/op
ParsingBenchmark.parseFoosC:gc.alloc.rate.norm thrpt 20 765800.586 ± 1.133 B/op
ParsingBenchmark.parseFoosA:gc.alloc.rate.norm thrpt 20 1488760.635 ± 1.228 B/op
ParsingBenchmark.parseFoosP:gc.alloc.rate.norm thrpt 20 987720.805 ± 1.551 B/op
ParsingBenchmark.parseFoosPico:gc.alloc.rate.norm thrpt 20 639464.525 ± 1.014 B/op
ParsingBenchmark.parseFoosS:gc.alloc.rate.norm thrpt 20 252256.440 ± 0.838 B/op
ParsingBenchmark.parseIntsC:gc.alloc.rate.norm thrpt 20 121272.129 ± 0.250 B/op
ParsingBenchmark.parseIntsA:gc.alloc.rate.norm thrpt 20 310280.151 ± 0.289 B/op
ParsingBenchmark.parseIntsP:gc.alloc.rate.norm thrpt 20 216448.089 ± 0.171 B/op
ParsingBenchmark.parseIntsPico:gc.alloc.rate.norm thrpt 20 141808.118 ± 0.239 B/op
ParsingBenchmark.parseIntsS:gc.alloc.rate.norm thrpt 20 109000.117 ± 0.229 B/op
PrintingBenchmark.printFoosC:gc.alloc.rate.norm thrpt 20 425240.419 ± 0.810 B/op
PrintingBenchmark.printFoosA:gc.alloc.rate.norm thrpt 20 621288.585 ± 1069.068 B/op
PrintingBenchmark.printFoosP:gc.alloc.rate.norm thrpt 20 351360.184 ± 0.356 B/op
PrintingBenchmark.printFoosPico:gc.alloc.rate.norm thrpt 20 431268.348 ± 1058.404 B/op
PrintingBenchmark.printFoosS:gc.alloc.rate.norm thrpt 20 372992.228 ± 0.442 B/op
PrintingBenchmark.printIntsC:gc.alloc.rate.norm thrpt 20 74464.067 ± 7.127 B/op
PrintingBenchmark.printIntsA:gc.alloc.rate.norm thrpt 20 239712.107 ± 0.206 B/op
PrintingBenchmark.printIntsP:gc.alloc.rate.norm thrpt 20 24144.025 ± 0.048 B/op
PrintingBenchmark.printIntsPico:gc.alloc.rate.norm thrpt 20 95472.072 ± 0.140 B/op
PrintingBenchmark.printIntsS:gc.alloc.rate.norm thrpt 20 24048.032 ± 0.062 B/op
The Foos
benchmarks work with a map containing case class values, and the Ints
ones are an array
of integers. C
suffixes indicate circe's throughput, A
is for Argonaut, P
is for
play-json, Pico
is for picopickle, and S
is for
spray-json. Note that spray-json's approach to failure handling is different from the
approaches of the other libraries listed here (it simply throws exceptions), and this difference
should be taken into account when comparing its results with the others.