2017-01-18 10 views
9

पर अंतर्निहित संकल्प धीमा क्यों है, सर्क जेसन एक वैल में निहित डीकोडर को बचाने की तुलना में निहित डीकोडर लुकअप के साथ धीमा क्यों है।सर्स जेसन के साथ रनटाइम

मैं उम्मीद करता हूं कि ये समान हों क्योंकि रनटाइम पर अंतर्निहित संकल्प किया जाता है।

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

स्कैला कभी रनटाइम पर अंतर्निहित हल नहीं करता – cchantep

उत्तर

17

इस बहुत सरल मामले कि जादूगरनी या बिल्कुल सामान्य व्युत्पत्ति को शामिल नहीं करता पर विचार करें:

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 

और अगर आप: मेरे डेस्कटॉप मशीन पर

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: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 इंस्टेंस को तत्काल करने की लागत है, क्योंकि इसे बेंचमार्क कोड के बाहर शुरुआत में एक बार तत्काल करने के विपरीत है। यह लागत अपेक्षाकृत छोटी है, और बड़े मानक के लिए यह देखना मुश्किल हो जाएगा।

+4

धन्यवाद बहुत ट्रैविस! – Stephen

संबंधित मुद्दे