2012-02-17 12 views
13

में टाइप क्लास पैटर्न का उपयोग करने का प्रदर्शन प्रभाव क्या है, वर्तमान में मैं अपने कोड के प्रदर्शन-प्रासंगिक भाग होने के लिए टाइप क्लास पैटर्न का व्यापक उपयोग कर रहा हूं। मैंने अक्षमता के कम से कम दो संभावित स्रोत बनाए।स्कैला

  1. निहित पैरामीटर संदेश कॉल के साथ पास हो जाते हैं। मुझे नहीं पता कि यह वास्तव में होता है या नहीं। हो सकता है कि स्केलेक केवल अंतर्निहित पैरामीटर डालें जहां उनका उपयोग किया जाता है और उन्हें विधि हस्ताक्षर से हटा दिया जाता है। यह उन मामलों में संभवतः संभव नहीं है जहां आप निहित पैरामीटर मैन्युअल रूप से सम्मिलित करते हैं, क्योंकि उन्हें केवल रनटाइम पर हल किया जा सकता है। अंतर्निहित पैरामीटर पास करने के संबंध में कौन से अनुकूलन लागू होते हैं? प्रकार वर्ग उदाहरण एक def (एक val के विपरीत) द्वारा प्रदान की गई

  2. हैं, वस्तु एक "प्रकार में वर्गीकृत विधि" के हर मंगलाचरण पर निर्मित किया जाना है। इस समस्या को JVM द्वारा संबोधित किया जा सकता है, जो वस्तु निर्माण को अनुकूलित कर सकता है। इन वस्तुओं का पुन: उपयोग करके इस मुद्दे को स्केलेक द्वारा भी दबाया जा सकता है। अंतर्निहित पैरामीटर ऑब्जेक्ट्स के निर्माण के संबंध में कौन से अनुकूलन लागू होते हैं?

और निश्चित रूप से जब प्रकार वर्ग पैटर्न लागू करने वहाँ अक्षमता का अतिरिक्त स्रोत हो सकता है। कृपया मुझे उनके बारे में बताओ।

उत्तर

8

आप सही मायने में अति उच्च प्रदर्शन कोड लिखने के बारे में परवाह है (और आप सोच सकते हैं आप करते हैं लेकिन बहुत गलत इस बारे में हो सकता है) तो typeclasses निम्नलिखित कारणों के लिए कुछ दर्द पैदा करने जा रहे हैं:

  • कई अतिरिक्त आभासी प्रणाली को बुलाती है
  • पुरातन की संभावना मुक्केबाजी (जैसे अगर monoids आदि के लिए scalaz के typeclasses का प्रयोग करके) def के माध्यम से
  • वस्तु कृतियों जो जरूरी हैं क्योंकि कार्यों पैरा नहीं किया जा सकता meterized "pimped" तरीकों

रनटाइम पर, JVM दूर गलत कृतियों में से कुछ को अनुकूलित कर सकते हैं का उपयोग करने की

  • वस्तु कृतियों (जैसे MA का निर्माण बस <*> पर कॉल करने के लिए), लेकिन scalac सहायता के लिए बहुत कुछ नहीं करता है। आप कुछ कोड संकलित करके यह मामूली रूप से देख सकते हैं जो टाइपक्लास का उपयोग करता है और -Xprint:icode का उपयोग तर्क के रूप में करता है।

    यहाँ एक उदाहरण है:

    import scalaz._; import Scalaz._ 
    object TC { 
        def main(args: Array[String]) { 
        println((args(0).parseInt.liftFailNel |@| args(1).parseInt.liftFailNel)(_ |+| _)) 
        } 
    } 
    

    और यहाँ ICODE है:

    final object TC extends java.lang.Object with ScalaObject { 
        def main(args: Array[java.lang.String]): Unit = scala.this.Predef.println(scalaz.this.Scalaz.ValidationMA(scalaz.this.Scalaz.StringTo(args.apply(0)).parseInt().liftFailNel()).|@|(scalaz.this.Scalaz.StringTo(args.apply(1)).parseInt().liftFailNel()).apply({ 
        (new anonymous class TC$$anonfun$main$1(): Function2) 
    }, scalaz.this.Functor.ValidationFunctor(), scalaz.this.Apply.ValidationApply(scalaz.this.Semigroup.NonEmptyListSemigroup()))); 
    def this(): object TC = { 
        TC.super.this(); 
    () 
    } 
    }; 
    @SerialVersionUID(0) final <synthetic> class TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2 extends scala.runtime.AbstractFunction0 with Serializable { 
        final def apply(): Int = TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2.this.v1$1; 
        final <bridge> def apply(): java.lang.Object = scala.Int.box(TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2.this.apply()); 
        <synthetic> <paramaccessor> private[this] val v1$1: Int = _; 
        def this($outer: anonymous class TC$$anonfun$main$1, v1$1: Int): anonymous class TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2 = { 
        TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2.this.v1$1 = v1$1; 
        TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2.super.this(); 
        () 
        } 
    }; 
    @SerialVersionUID(0) final <synthetic> class TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1 extends scala.runtime.AbstractFunction0$mcI$sp with Serializable { 
        final def apply(): Int = TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1.this.apply$mcI$sp(); 
        <specialized> def apply$mcI$sp(): Int = TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1.this.v2$1; 
        final <bridge> def apply(): java.lang.Object = scala.Int.box(TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1.this.apply()); 
        <synthetic> <paramaccessor> private[this] val v2$1: Int = _; 
        def this($outer: anonymous class TC$$anonfun$main$1, v2$1: Int): anonymous class TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1 = { 
        TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1.this.v2$1 = v2$1; 
        TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1.super.this(); 
    () 
        } 
    }; 
    @SerialVersionUID(0) final <synthetic> class TC$$anonfun$main$1 extends scala.runtime.AbstractFunction2$mcIII$sp with Serializable { 
        final def apply(x$1: Int, x$2: Int): Int = TC$$anonfun$main$1.this.apply$mcIII$sp(x$1, x$2); 
        <specialized> def apply$mcIII$sp(v1$1: Int, v2$1: Int): Int = scala.Int.unbox(scalaz.this.Scalaz.mkIdentity({ 
    (new anonymous class TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2(TC$$anonfun$main$1.this, v1$1): Function0) 
    }).|+|({ 
        (new anonymous class TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1(TC$$anonfun$main$1.this, v2$1): Function0) 
    }, scalaz.this.Semigroup.IntSemigroup())); 
    final <bridge> def apply(v1: java.lang.Object, v2: java.lang.Object): java.lang.Object = scala.Int.box(TC$$anonfun$main$1.this.apply(scala.Int.unbox(v1), scala.Int.unbox(v2))); 
        def this(): anonymous class TC$$anonfun$main$1 = { 
        TC$$anonfun$main$1.super.this(); 
        () 
        } 
    } 
    

    }

    आप ऑब्जेक्ट निर्माण की एक बड़ी राशि यहाँ

  • +0

    तो एक चल रहा है देख सकते हैं सुझाव जो मैंने आपके उत्तर से पढ़ा है वह 'scalaz.Monoid' को प्रतिस्थापित कर सकता है, जिसका मैं वास्तव में उपयोग कर रहा हूं, spe के साथ अपने संस्करण द्वारा cialization? हालांकि विशेषज्ञता बहुत छोटी लगती है ... यहां तक ​​कि 'न्यूमेरिक' भी ऐसा नहीं लगता है। – ziggystar

    +0

    मैं विशेषज्ञता टीबी के बारे में अच्छी तरह से स्पष्ट होगा। अगर मैं आपके जूते में था तो मैं * बहुत, निश्चित रूप से * बनना चाहता हूं कि मुझे कोड के प्रदर्शन की हर आखिरी बूंद को निचोड़ने की आवश्यकता थी।क्या आपको यकीन है कि आप करते हैं? अगर चीज को धातु के करीब होना है, तो मैं कहूंगा कि आपको म्यूटेबल संग्रह, अनिवार्य कोड और लूप के दौरान वापस जाना होगा। वास्तव में कोई अन्य उत्तर नहीं है –

    +0

    यह वास्तव में यथासंभव तेज़ होना नहीं है। लेकिन मैं मुक्केबाजी के प्रदर्शन प्रभाव नहीं लेना चाहता हूं। मैं वर्तमान में आदिम सरणी का उपयोग कर रहा हूं (उन्हें म्यूट किए बिना)। समस्या के बारे में, बड़ी समस्या स्थान पर लागू करने के लिए कोड को बहुत सामान्य रखना संभव है (मैं बीजगणितीय के छल्ले को अबास्ट्रक्शन के रूप में भी उपयोग कर रहा हूं)। वर्तमान में मैं प्रदर्शन के बीच फैसला नहीं करना चाहता (जैसे मुक्केबाजी 10x हिट ले रहा है) और अमूर्तता; यह एक आसान विकल्प नहीं है और मुझे आश्चर्य है कि मैं दोनों को लेने के साथ कितना दूर जा सकता हूं। – ziggystar