Implement a faster circe case class encoder


#1

Hello, in the past six months, I have implemented a shapeless-like library that solves another problem(like auto mapping between slick’s table and model).
Now I’ve finished 90% but no documentation and not tested.
When I was trying to implement a circe case class encoder, I found that my implementation performance was better than the official one.

Here the jmh report https://github.com/djx314/asuna-jmh
and here’s the repo address https://github.com/scalax/asuna

In the use case of upickle’s self performance test(Test02.scala), asuna-circe uses circe’s api to show almost the same performance as upickle. In the use case of simple case class, asuna-circe is more faster than raw circe and upickle.
The principle is simple: force the user to define the encoder using valEncoder(strict or lazy) and defEncoder(non-strict). In valEncoder, use lazy value(need to support circular dependencies) to cache encoders in every field.

This implementation only uses about 150 line by only defining implicit base on asuna. And it’s easy to support snake-name and default value by asuna’s build-in API.

On top of this, we can redefine the field names, encoders, or both.

The above example also shows how to cache ‘non type parameter’ field’s encoders when the case class has type parameters.


#2

Great and welcome, the benchmark result seems very promising.


#3

Hm, I have to repost the benchmark result here in case someone not seen it:

asuna-jmh

A jmh test for circe, upickle and asuna-circe

Data for source file in Test01.scala with sbt jmh1 .

[info] Benchmark                Mode  Cnt       Score       Error  Units
[info] AbcTest.asunaCirceTest  thrpt    3  389331.318 ± 18215.636  ops/s
[info] AbcTest.rawCirceTest    thrpt    3  324753.521 ±  8722.148  ops/s
[info] AbcTest.upickleTest     thrpt    3  320946.408 ± 16224.948  ops/s

Data for source file in Test02.scala with sbt jmh2 .

[info] Benchmark                Mode  Cnt      Score      Error  Units
[info] DefTest.asunaCirceTest  thrpt    3  86185.818 ± 1958.218  ops/s
[info] DefTest.rawCirceTest    thrpt    3  77002.256 ± 2412.541  ops/s
[info] DefTest.upickleTest     thrpt    3  87461.515 ± 8208.228  ops/s