scala: jmhでreifnedのパフォーマンスを(適当に)調べてみる
環境 Scala 2.13.8
ちょっと気になってrefinedのPositiveなどに比べて、requireで契約的に正数を縛る場合、どのくらいのパフォーマンス差があるか調べてみた。
コードはだいぶ適当だが以下
package bench import cats.implicits._ import eu.timepit.refined._ import eu.timepit.refined.api._ import eu.timepit.refined.auto._ import eu.timepit.refined.numeric._ import eu.timepit.refined.types.numeric._ import scala.util._ import org.openjdk.jmh.annotations._ class JMHSample { @throws def convertPositiveInt(i: Int): Int = { require(i >= 0) i } @Benchmark def measureAgreementPosInt(): Either[String, Int] = { try { Right[String, Int](convertPositiveInt(1)) } catch { case t: Throwable => Left[String, Int](t.getMessage) } } @Benchmark def measureAgreementPosIntFPLike(): Either[String, Int] = { Try(convertPositiveInt(1)).toEither.leftMap(t => t.getMessage) } @Benchmark def measurePosInt(): Either[String, PosInt] = { RefType.applyRef[PosInt](1) } @Benchmark def measureIntRefinedPositive(): Either[String, Int Refined Positive] = { refineV[Positive](1) } }
結果
sbt:jmh-example> Jmh / run -i 3 -wi 3 -f1 -t 1 ... [info] Benchmark Mode Cnt Score Error Units [info] JMHSample.measureAgreementPosInt thrpt 3 365097651.422 ± 19080986.848 ops/s [info] JMHSample.measureAgreementPosIntFPLike thrpt 3 344466648.190 ± 20924629.667 ops/s [info] JMHSample.measureIntRefinedPositive thrpt 3 73142259.692 ± 16294716.321 ops/s [info] JMHSample.measurePosInt thrpt 3 78952274.799 ± 58359188.751 ops/s [success] Total time: 241 s (04:01), completed 2022/10/16 14:03:36
おおむね1/3~1/5くらいrefinedの方がパフォーマンスは劣化する。 とはいえ普通にアプリケーション実装するときとかは、I/Oとかと比べれば微細なレベルだと思うので、有用な時は使えばよいと思う。