2011-09-22 8 views
8

पायथन re मॉड्यूल पर दस्तावेज़ पढ़ने के दौरान मैंने re.py स्रोत कोड पर एक नज़र डालने का निर्णय लिया।पायथन री मॉड्यूल का कैश समाशोधन

जब मैं इसे खोला, मैं इस पाया:

_cache = {} 
_MAXCACHE = 100 

def _compile(*key): 
    cachekey = (type(key[0]),) + key 
    p = _cache.get(cachekey) 
    if p is not None: 
     return p 

    #...Here I skip some part of irrelevant to the question code... 

    if len(_cache) >= _MAXCACHE: 
     _cache.clear() 
    _cache[cachekey] = p 
    return p 

क्यों कैश जब यह प्रविष्टियों की _MAXCACHE तक पहुँच जाता है _cache.clear() का उपयोग कर को मंजूरी दे दी है?

कैश साफ़ करने और स्क्रैच से शुरू करने के लिए यह सामान्य दृष्टिकोण है?

क्यों अभी तक सबसे लंबे समय तक उपयोग नहीं किया गया है कैश किए गए मान को हटा दिया गया है?

+3

दिलचस्प सवाल। मुझे लगता है कि यह डेवलपर के उस हिस्से पर आलस्य हो सकता था जिसने इस कोड को लिखा था, या शायद "जटिल जटिल से बेहतर है" सोच। :-) – NPE

+0

मैंने सोचा कि कुछ वैज्ञानिक शोध हो सकते हैं जो आकार में कुछ निरंतर मूल्य तक पहुंचने पर कैश साफ़ करने के इस दृष्टिकोण को उचित ठहराते हैं। – ovgolovin

+0

यहां ट्रैक किए गए विकास के तहत नए रेगेक्स मॉड्यूल के स्रोत को देखना दिलचस्प हो सकता है: http://bugs.python.org/issue2636। विवरण में "स्मार्ट कैशिंग" शब्द शामिल है, इसलिए उस क्षेत्र में कुछ सुधार किए जा सकते हैं। –

उत्तर

3

अगर मुझे लगता है कि मैं कहूंगा कि यह कैश में कितने समय तक व्यक्तिगत मूल्यों को संग्रहीत किया गया था, यह ट्रैक रखने से बचने के लिए ऐसा किया गया था, जिससे स्मृति और प्रोसेसिंग ओवरहेड दोनों बन जाएंगे। चूंकि उपयोग की जाने वाली कैशिंग ऑब्जेक्ट एक शब्दकोश है, जो स्वाभाविक रूप से अनियंत्रित है, यह जानने का कोई अच्छा तरीका नहीं है कि किसी अन्य कैशिंग ऑब्जेक्ट के बिना ऑर्डर आइटम जोड़े गए हैं। इसे मानक शब्दकोष के स्थान पर ऑर्डर्ड डिक्ट का उपयोग करके संबोधित किया जा सकता है, मानते हुए कि आप पाइथन> = 2.7 के साथ काम कर रहे हैं, लेकिन अन्यथा, आपको कैशिंग को लागू करने के तरीके को फिर से डिजाइन करने के तरीके को फिर से डिजाइन करना होगा clear()

+0

'ऑर्डर्ड डिक्ट' का उपयोग करके 'कैश' को कार्यान्वित करना मुश्किल है? मेरे दिमाग में, तत्वों के क्रम का उपयोग करके अंतिम उपयोग के क्रम में उन्हें व्यवस्थित करना संभव हो जाता है। और एक संकलित ऑब्जेक्ट का पुन: उपयोग करने के लिए केवल कैश किए गए मान को 'ऑर्डर्ड डिक्ट' की शुरुआत में पॉप अप करके और फिर शब्दकोश में रखकर स्थानांतरित करने की आवश्यकता होगी। – ovgolovin

+0

@ovgolovin - आप सूची के नीचे इसे वापस ले जाने के लिए मूल्य को पॉप/दोबारा जोड़ सकते हैं, संभव है। मैं इसे मुश्किल नहीं मानूंगा, नहीं। –

+0

मैंने सोचा कि कुछ वैज्ञानिक शोध हो सकते हैं जो आकार में कुछ निरंतर मूल्य तक पहुंचने पर कैश साफ़ करने के इस दृष्टिकोण को उचित ठहराते हैं। – ovgolovin

1

कैशिंग का बिंदु फ़ंक्शन के औसत कॉल समय को कम करना है। _cache में अधिक जानकारी रखने के साथ जुड़े ओवरहेड और इसे साफ़ करने के बजाए इसे काटकर उस औसत कॉल समय में वृद्धि होगी। _cache.clear() कॉल जल्दी से पूरा हो जाएगा, और भले ही आप अपना कैश खो दें, कैश स्थिति को बनाए रखने के लिए बेहतर है और जब सीमा तक पहुंच जाती है तो कैश से अलग-अलग तत्वों को हटाने का ओवरहेड होता है।

  1. कैश हिट (बहुत ही कम)
  2. कैश छूट जाए (अब)
  3. आवृत्ति पर औसत कॉल समय पर औसत कॉल समय:

    कुछ चीजें जब कैश क्षमता की गणना के बारे में सोचने के लिए कर रहे हैं कैश हिट (काफी असामान्य)

  4. कॉल समय था जब कैश साफ़ कर या कम कर दिए हैं (काफी असामान्य) है

की प्रश्न # 3 बढ़ रहा है अगर इसका मतलब है कि # 2 और # 4 बढ़ रहा है। मेरा अनुमान है कि यह नहीं करता है, या अंतर पर्याप्त नगण्य है कि कोड को सरल रखना बेहतर है।

+0

लेकिन अधिक जानकारी रखने के साथ जुड़े ओवरहेड '_cache' अनुमानित होगा। लेकिन स्पोरैडिक पलों में '_cache' को साफ़ करने से कैश दक्षता का आकलन बहुत परेशान हो जाएगा, क्योंकि यह कैश' साफ़ होने पर क्षणों पर बहुत भरोसेमंद होगा। – ovgolovin

5

कैशिंग के संबंध में 3.3 के लिए निर्धारित एक नए regex मॉड्यूल के डेवलपर्स में से एक उद्धरण है, यह उन सुविधाओं की एक सूची का हिस्सा है जो नए मॉड्यूल को वर्तमान re मॉड्यूल से अलग करते हैं।

7) थ्रैशिंग स्थिति को बेहतर तरीके से संभालने के लिए पुनः संकलित अभिव्यक्ति कैश को संशोधित करें। वर्तमान में, जब नियमित अभिव्यक्ति संकलित की जाती है, परिणाम कैश किया जाता है ताकि यदि एक ही अभिव्यक्ति को फिर से संकलित किया गया हो, इसे कैश से पुनर्प्राप्त किया गया है और कोई अतिरिक्त कार्य नहीं किया जाना है। यह कैश 100 प्रविष्टियों का समर्थन करता है। एक बार 100 वीं प्रविष्टि तक पहुंचने के बाद, कैश साफ़ कर दिया गया है और एक नया संकलन होना चाहिए।खतरा, यह सब दुर्लभ हो सकता है, यह है कि कोई भी यह देखने के लिए 100 वीं अभिव्यक्ति को संकलित कर सकता है कि एक इसे पुन: संकलित करता है और इसे फिर से एक ही काम करना पड़ता है जब यह 3 अभिव्यक्तियों को किया जा सकता है। इस तर्क को थोड़ा सा संशोधित करके, एक मनमाना काउंटर स्थापित करना संभव है जो प्रत्येक संकलित प्रविष्टि को पर एक टाइम स्टैंप देता है और क्षमता तक पहुंचने पर पूरे कैश को साफ़ करने के बजाय, केवल रखते हुए कैश के सबसे पुराने आधे को खत्म कर देता है आधे जो हाल ही में है। इससे उन मामलों में थ्रैशिंग की संभावना को सीमित करना चाहिए जहां नियमित अभिव्यक्तियों की एक बड़ी संख्या लगातार पुन: संकलित होती है। इसके अतिरिक्त, मैं सीमा को 256 प्रविष्टियों में अपडेट कर दूंगा, जिसका अर्थ है कि 128 सबसे हाल ही में रखा गया है।

http://bugs.python.org/issue2636

यह संकेत मिलता है कि यह अधिक संभावना डेवलपर या "पठनीयता पर जोर देने के" है कि मौजूदा कैशिंग व्यवहार बताते हैं के आलस्य है लगता है।

+0

मैंने 'regex' मॉड्यूल का स्रोत कोड खोला है (मैं इसे लगभग पखवाड़े के लिए उपयोग कर रहा हूं)। कोड को साफ़ करने के लिए ज़िम्मेदार कोड का ब्लॉक निम्न है 'यदि लेन (_cache)> = _MAXCACHE: shrink_cache (_cache, _named_args, _MAXCACHE) '। लेकिन मुझे मॉड्यूल पर कोई 'shrink_cache' फ़ंक्शन नहीं मिला है। ऐसा कोई काम नहीं है। – ovgolovin

+0

फिर भी, लेखक कैश के बड़े हिस्सों को खत्म करने के साथ चिपक जाता है, जब इसकी आवश्यकता होती है तो एकल तत्व नहीं। नया दृष्टिकोण कैश के कम से कम आधा भाग को समाप्त करता है। – ovgolovin

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