当前位置:  开发笔记 > 编程语言 > 正文

使用Circe Json,为什么隐式解析在运行时会变慢

如何解决《使用CirceJson,为什么隐式解析在运行时会变慢》经验,为你挑选了1个好方法。

与将隐式解码器保存为val相比,为什么Circe Json使用隐式解码器查找更慢.

我希望这些是相同的,因为隐式解析是在运行时完成的.

import io.circe._
import io.circe.generic.auto._
import io.circe.jackson
import io.circe.syntax._

private val decoder = implicitly[Decoder[Data.Type]]
def decode(): Either[Error, Type] = {
  jackson.decode[Data.Type](Data.json)(decoder)
}

def decodeAuto(): Either[Error, Type] = {
  jackson.decode[Data.Type](Data.json)
}


[info] DecodeTest.circeJackson             thrpt  200   69157.472 ± 283.285  ops/s
[info] DecodeTest.circeJacksonAuto         thrpt  200   67946.734 ± 315.876  ops/s

完整的回购可以在这里找到. https://github.com/stephennancekivell/some-jmh-json-benchmarks-circe-jackson



1> Travis Brown..:

考虑这个更简单的情况,根本不涉及循环或泛化推导:

package demo

import org.openjdk.jmh.annotations._

@State(Scope.Thread)
@BenchmarkMode(Array(Mode.Throughput))
class OrderingBench {
  val items: List[(Char, Int)] = List('z', 'y', 'x').zipWithIndex
  val tupleOrdering: Ordering[(Char, Int)] = implicitly

  @Benchmark
  def sortWithResolved(): List[(Char, Int)] = items.sorted

  @Benchmark
  def sortWithVal(): List[(Char, Int)] = items.sorted(tupleOrdering)    
}

在我的台式机上2.11我得到了这个:

Benchmark                        Mode  Cnt         Score        Error  Units
OrderingBench.sortWithResolved  thrpt   40  15940745.279 ± 102634.860  ps/s
OrderingBench.sortWithVal       thrpt   40  16420078.932 ± 102901.418  ops/s

如果你看一下分配,差异就会大一些:

Benchmark                                            Mode  Cnt    Score   Error   Units
OrderingBench.sortWithResolved:gc.alloc.rate.norm  thrpt   20  176.000 ±  0.001    B/op
OrderingBench.sortWithVal:gc.alloc.rate.norm       thrpt   20  152.000 ±  0.001    B/op

你可以通过爆发告诉我们发生了什么reify:

scala> val items: List[(Char, Int)] = List('z', 'y', 'x').zipWithIndex
items: List[(Char, Int)] = List((z,0), (y,1), (x,2))

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> showCode(reify(items.sorted).tree)
res0: String = $read.items.sorted(Ordering.Tuple2(Ordering.Char, Ordering.Int))

Ordering.Tuple2是一个实例化的通用方法Ordering[(Char, Int)].这与我们定义我们时发生的情况完全相同tupleOrdering,但区别在于val它发生一次的情况,而在它被隐式解析的情况下,它每次sorted被调用时都会发生.

因此,您所看到的差异只是Decoder在每个操作中实例化实例的成本,而不是在基准代码之外的一开始实例化它.这个成本相对较小,对于更大的基准测试,它将更难以看到.


非常感谢Travis!
推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有