jsoniter-scala-circeを試してみる

Soniter-Scala にCirceと一緒に使えるモジュールjsoniter-scala-circe はインポート文を追加するだけで特定のクラス(Java.time._やBigIntなど)のSerDeを高速化することができます。
2022.12.29

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こちらのブログ記事 “The fastest and safest JSON parser and serializer for Scala” で紹介されていたJSoniter-Scala にCirceと一緒に使えるモジュールjsoniter-scala-circe があったので試してみました。

JSoniter-Scalaとは

名前の通りScalaのJSONエンコーダー/デコーダーです。詳しくは前述の記事が詳しいです。

そのモジュールであるjsoniter-scala-circe はGitHubのReadMEによると以下のように紹介されています。

the circe booster for faster parsing/serialization to/form circe AST and decoding/encoding of java.time._ and BigInt types.

試してみる

ドキュメントには上記のような説明だけで具体的な使い方の言及がなかったので実際に試してみました。 といってもCirceCodecsからデコーダ/エンコーダーをインポートするだけでした。

import $ivy.`com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-circe:2.20.0`
import com.github.plokhotnyuk.jsoniter_scala.circe.CirceCodecs.*
import io.circe.*
import io.circe.syntax.*

object JSoniterCirce {

  @main
  def main = {
    val json = BigInt(2022).asJson
    println("encoder: " + summon[Encoder[BigInt]])
    println("decoder: " + summon[Decoder[BigInt]])
    println("encoded: " + json)
    println("decoded: " + json.as[BigInt].fold(throw _, identity))
  }

}

念のためsummonされるエンコーダ/デコーダーのインスタンスを確認すると以下のようにjsoniterのものが使われているのがわかります。

encoder: com.github.plokhotnyuk.jsoniter_scala.circe.CirceCodecs$$anon$1@204f30ec
decoder: com.github.plokhotnyuk.jsoniter_scala.circe.CirceCodecs$$anon$1@204f30ec
encoded: 2022
decoded: 2022

パフォーマンス

公開されているベンチマークをみるとBigInt/BigDecimalとLocalDatetimeを扱うパターンではCirceよりもかなりいいパフォーマンスを出しているのでこれらを含むケースではこのエンコーダー/デコーダーを採用することで改善が期待できるのではと思います。

しかしわざわざこれを採用するほどJSONのSerDeが負荷になっているケースではJSoniser自体の採用を検討しても良いかもしれません。

まとめ

JSoniter-ScalaのCirce向けのエンコーダー/デコーダーモジュールであるjsoniter-scala-circeを試してみました。対象としているのが一部のクラスだけですがインポートするだけで使えるのは手軽ではないでしょうか。