对于Circe Json,为什么隐式解析在运行时较慢
为什么Circe Json使用隐式解码器查找比将隐式解码器保存到val慢 我希望它们是相同的,因为隐式解析是在运行时完成的对于Circe Json,为什么隐式解析在运行时较慢,json,scala,circe,Json,Scala,Circe,为什么Circe Json使用隐式解码器查找比将隐式解码器保存到val慢 我希望它们是相同的,因为隐式解析是在运行时完成的 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] =
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
完整的回购协议可以在这里找到。
考虑这个更简单的情况,它根本不涉及循环或泛型派生:
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
你可以通过说出具体化来判断发生了什么:
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
这里是一个通用方法,它实例化了排序[(Char,Int)]
。这与我们定义tupleOrdering
时发生的情况完全相同,但区别在于在val
情况下,它只发生一次,而在隐式解析的情况下,它每次调用sorted
时都会发生
因此,您所看到的差异只是在每个操作中实例化解码器
实例的成本,而不是在基准代码之外的一开始一次性实例化它。这一成本相对较小,对于更大的基准测试来说,这将更难看到。Scala永远不会在运行时解决隐式问题,多亏了Travis!