2010-03-11 10 views
12

हम हाल ही में हमारे कोड प्रोफाइलिंग कर रहे हैं और हम कुछ कष्टप्रद हॉटस्पॉट में आ गए हैं। वे के रूप में कर रहे हैंधीमी स्केल assert

assert(a == b, a + " is not equal to " + b) 

क्योंकि इनमें से कुछ का दावा है कोड में समय की एक बड़ी राशि स्ट्रिंग concat को जोड़ने के लिए शुरू होता है कहा जाता है हो सकता है। assert के रूप में परिभाषित किया गया है:

def assert(assumption : Boolean, message : Any) = .... 

क्यों नहीं यह के रूप में परिभाषित किया गया है: इस तरह यह lazily मूल्यांकन करेगा

def assert(assumption : Boolean, message : => Any) = .... 

। यह देखते हुए कि यह परिभाषित नहीं किया गया है कि इस तरह एक संदेश परम के साथ जोर देने का एक इनलाइन तरीका है जिसका मूल्यांकन आलसी है?

धन्यवाद

+6

उन है कि पता नहीं है के लिए, यह 2.8 में तय हुई थी। – Dave

उत्तर

16

आलसी मूल्यांकन में फ़ंक्शन ऑब्जेक्ट के लिए कुछ ओवरहेड भी है। यदि आपका संदेश ऑब्जेक्ट पहले से ही पूरी तरह से बनाया गया है (एक स्थिर संदेश) यह ओवरहेड अनावश्यक है।

के लिए आपके उपयोग के मामले sprintf शैली होगा उचित विधि:

assert(a == b, "%s is not equal to %s", a, b) 

जब तक वहाँ एक speciaized समारोह

assert(Boolean, String, Any, Any) 
है

इस कार्यान्वयन कोई भूमि के ऊपर या वर की लागत है Args

assert(Boolean, String, Any*) 

सामान्य मामले के लिए।

को लागू करने toString lazily का मूल्यांकन किया जाएगा, लेकिन पढ़ने योग्य नहीं है:

assert(a == b, new { override def toString = a + " is not equal to " + b }) 
+0

धन्यवाद थॉमस। मैंने आलसी मूल्यांकन के ऊपरी हिस्से को नहीं माना था। हमारे कोड से आलसी मूल्यांकन के ऊपरी हिस्से स्ट्रिंग कॉन्सट से बहुत कम है, इसलिए मुझे लगता है कि हम अपनी खुद की जोर विधि लिखने के साथ जाएंगे। यह सुंदर नहीं है लेकिन चीजों को बहुत तेज करता है। – Dave

-2

प्रयास करें: assert(a==b, "%s is not equals to %s".format(a,b)) प्रारूप केवल जब ज़ोर स्ट्रिंग की जरूरत है बुलाया जाना चाहिए। प्रारूप को रिचस्ट्रिंग में अंतर्निहित के माध्यम से जोड़ा गया है।

+1

यह ** गलत ** है क्योंकि प्रश्नकर्ता ने हाइलाइट किया है: कि जोर विधि एक 'कोई' लेती है और नहीं '=> कोई भी' –

+1

मुझे यकीन है कि स्वरूप में कोई जादू नहीं है, तो यह सिर्फ सामान्य के रूप में बुलाया जाता है, चाहे एक == बी सत्य है या नहीं। – Dave

+0

डी ओह। मैं एक id10t हूँ। यह अब स्पष्ट है। –

1

थॉमस 'जवाब महान है, लेकिन सिर्फ मामले में आप पिछले जवाब का विचार पसंद लेकिन unreadability नापसंद करते हैं, आप इसे चारों ओर प्राप्त कर सकते हैं:

object LazyS { 
    def apply(f: => String): AnyRef = new { 
    override def toString = f 
    } 
} 

उदाहरण:

object KnightSpeak { 
    override def toString = { println("Turned into a string") ; "Ni" } 
} 

scala> assert(true != false , LazyS("I say " + KnightSpeak)) 

scala> println(LazyS("I say " + KnightSpeak)) 
Turned into a string 
I say Ni 
7

यह नाम से है, मैंने इसे एक साल पहले बदल दिया था।

http://www.scala-lang.org/node/825

वर्तमान Predef:

@elidable(ASSERTION) 
def assert(assertion: Boolean, message: => Any) { 
    if (!assertion) 
    throw new java.lang.AssertionError("assertion failed: "+ message) 
} 
+0

@extempore: क्या यह केवल 2.8 के लिए है? या 2.7 भी? –