json4sのserializeとdeserializeのbenchmark

Scala 3部分でserializeとdeserializeに対応したけれど、全然仕組みが違うので速度大幅に劣化してるのか、思ったより変わらないのか?を調べた

ベンチマーク用のコードは下の方。

それぞれ Jmh/run -i 10 -wi 10 -f1 -t1Scala 3.7.3と2.13.17で計測した結果

Scala 3.7.3

[info] Benchmark          Mode  Cnt       Score      Error  Units
[info] Test.deserialize  thrpt   10  779276.269 ± 3644.732  ops/s
[info] Test.serialize    thrpt   10  502060.955 ± 2980.308  ops/s

Scala 2.13.17

[info] Benchmark          Mode  Cnt       Score      Error  Units
[info] Test.deserialize  thrpt   10  854486.078 ± 6030.549  ops/s
[info] Test.serialize    thrpt   10  499409.945 ± 2681.230  ops/s

大幅に遅くなったりするのかと思っていたけれど、ほとんど変わらない???

他のjsonライブラリと比較してどうなるのか?は調べてないですが、既にjson4s使ってる人がScala 3移行するにあたっては思ったより心配いらなそう。

ただ、以下のような特定のcase classの場合しか調べてないので、もっと別のパターンで遅くなる可能性は否定出来ないですが。

あるいは、繰り返してるから差が出ないだけであって、初回は遅い、などもあり得る・・・かもしれませんが、そこも詳細に計測してません。

build.sbt

enablePlugins(JmhPlugin)

scalaVersion := "3.7.3"

scalacOptions += "-deprecation"

libraryDependencies += "io.github.json4s" %% "json4s-native" % "4.1.0"

libraryDependencies ++= {
  scalaBinaryVersion.value match {
    case "3" =>
      Seq("org.scala-lang" %% "scala3-staging" % scalaVersion.value)
    case _ =>
      Nil
  }
}

project/build.properties

sbt.version=1.11.7

project/plugins.sbt

addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.8")

src/main/scala/Main.scala

package example

import org.json4s._
import org.openjdk.jmh.annotations.Benchmark

case class A1(
  x1: Int,
  x2: String,
  x3: Boolean,
  x4: List[Int],
  x5: List[String],
  x6: Map[Int, Int],
  x7: Option[Long],
)

object A1 {
  val value: A1 = A1(
    2,
    "a",
    false,
    List(10, 20),
    List("x", "y"),
    Map(333 -> 444),
    Some(-9999),
  )

  val json: JValue = JObject(
    List(
      ("x1", JInt(2)),
      ("x2", JString("a")),
      ("x3", JBool(false)),
      ("x4", JArray(List(JInt(10), JInt(20)))),
      ("x5", JArray(List(JString("x"), JString("y")))),
      ("x6", JObject("333" -> JInt(444))),
      ("x7", JInt(-9999))
    )
  )
}

class Test {

  implicit def format: org.json4s.Formats =
    org.json4s.DefaultFormats

  @Benchmark
  def serialize(): String = {
    org.json4s.native.Serialization.write(A1.value)
  }

  @Benchmark
  def deserialize(): A1 = {
    Extraction.extract[A1](A1.json)
  }

}