2016-01-21 3 views
5

पर मौजूद गैर-मौजूद विशेषता के लिए गेटर को आविष्कार करने वाला कॉल रेफैक्टर करते समय इसमें दौड़ें। प्राप्त करने के लिए कॉलप्रॉपर्टीज() हमारे सीपीयू उपयोग को तेज करने के कारण पैदा कर रहे थे। हमने जो खोजा है वह यह है कि यदि आपके पास एक संबद्ध विशेषता के बिना गेटटर है, तो जब आप प्रॉपर्टीज() प्राप्त करने के लिए कॉल करते हैं तो गेटर को 1000 बार से अधिक कहा जाता है। फिक्स/वर्कअराउंड स्पष्ट है और हम जानते हैं कि मेटाप्रोग्रामिंग के साथ इसका कुछ संबंध है लेकिन यह क्यों हो रहा है (ग्रोवी स्रोत में क्या बिंदु)? नीचे groovy स्क्रिप्ट कोड देखें:ग्रोवी getProperties() 1000 बार

class tester { 

    int count = 0 

    public getVar() { 
     println count++ + " getVar() called!" 
     return var 
    } 
} 

def t = new tester() 

t.getProperties() 

println "done!" 

आपको 1000 बार से अधिक getVar() को देखना चाहिए। 1068 हमारे लिए सटीक होना चाहिए।

+1

काफी अजीब है। मैंने बस ग्रोवी वेब कंसोल http://groovyconsole.appspot.com/ में यह कोशिश की और मुझे इसे 110 बार निष्पादित किया गया। –

+9

यह इस पंक्ति के कारण होता है 'वापसी var'। यह वास्तव में 'getVar()' को रिकर्सन में ही आमंत्रित कर रहा है क्योंकि 'रिटर्न var'' वापसी वापसी वार() 'के रूप में समान है। जब तक ढेर बहती है तब तक यह गिनती को प्रिंट करता है। – dmahapatro

+2

'वापसी var' समस्या है। –

उत्तर

0

प्रश्न में शायद ही प्रश्नों का उत्तर दिया गया है लेकिन मैंने "ग्रोवी स्रोत में किस बिंदु" का जवाब देने के लिए थोड़ा गहरा खोला है।

जब आप tester के कहने पर getProperties() फोन ग्रूवी अपना जादू करना होगा और अंत में DefaultGroovyMethods#getProperties(Object) जो (ग्रूवी 2.4.7 में) इस तरह दिखता फोन:

public static Map getProperties(Object self) { 
    List<PropertyValue> metaProps = getMetaPropertyValues(self); // 1 
    Map<String, Object> props = new LinkedHashMap<String, Object>(metaProps.size()); 

    for (PropertyValue mp : metaProps) { 
     try { 
      props.put(mp.getName(), mp.getValue()); // 2 
     } catch (Exception e) { 
      LOG.throwing(self.getClass().getName(), "getProperty(" + mp.getName() + ")", e); 
     } 
    } 
    return props; 
} 

पहले, ग्रूवी के मेटा गुण निर्धारित करता है दिया गया वस्तु (देखें 1)।

  • var:: यह तीन गुण वापस आ जाएगी मनुष्य केवल (getVar()), कोई सेटर, कोई क्षेत्र
  • class: मनुष्य केवल (Object से विरासत में मिली), कोई सेटर, कोई क्षेत्र
  • count: गेटर, सेटर (ग्रोवी द्वारा उत्पन्न दोनों) और फ़ील्ड

आप t.getMetaPropertyValues() पर कॉल करके आसानी से इसे सत्यापित कर सकते हैं।

अगला, ग्रोवी प्रत्येक संपत्ति का वर्तमान मूल्य प्राप्त करने का प्रयास करता है और इसे मानचित्र में रखता है (देखें 2)। जब यह var तक पहुंचता है, तो यह याद करता है कि var में गेटर (अर्थात् getVar()) है और इसे कॉल करता है। getVar() हालांकि, var फिर से लौटाता है। ग्रोवी के लिए, यह वही संपत्ति है जो पहले चरण में निर्धारित है। एक बार फिर, यह अपने गेटर getVar() पर कॉल करता है और अंतहीन पाश शुरू होता है।

कुछ बिंदु पर, JVM पर निर्भर करता है, यह एक StackOverflowError में परिणाम है, जो वास्तव में है क्या इस साइट के बारे में सब :-D