2013-02-07 19 views
16

this question का जवाब देते समय (और एक ही प्रश्न के लिए this answer पढ़कर), मैंने सोचा कि मुझे पता था कि पाइथन कैश कैसे regexes।क्यों असम्पीडित हैं, बार-बार रीजिक्स का उपयोग पायथन 3 में इतना धीमा है?

लेकिन फिर मैंने सोचा कि मैं यह परीक्षण करना चाहते हैं, दो स्थितियों की तुलना:

  1. एक सरल regex की एक एकल संकलन, तो 10 कि संकलित regex के अनुप्रयोगों।
  2. एक असम्पीडित रेगेक्स के 10 अनुप्रयोग (जहां मुझे थोड़ा खराब प्रदर्शन की उम्मीद होगी क्योंकि रेगेक्स को एक बार संकलित करना होगा, फिर कैश किया जाएगा, और उसके बाद 9 बार कैश में देखा जाएगा)।

हालांकि, परिणाम (अजगर 3.3 में) चक्कर गया:

>>> import timeit 
>>> timeit.timeit(setup="import re", 
... stmt='r=re.compile(r"\w+")\nfor i in range(10):\n r.search(" jkdhf ")') 
18.547793477671938 
>>> timeit.timeit(setup="import re", 
... stmt='for i in range(10):\n re.search(r"\w+"," jkdhf ")') 
106.47892003890324 

है कि 5.7 गुना धीमी! पायथन 2.7 में, अभी भी 2.5 के कारक में वृद्धि हुई है, जो कि मुझे उम्मीद से भी अधिक है।

क्या पाइथन 2 और 3 के बीच रेगेक्स का कैशिंग बदल गया है? The docs ऐसा सुझाव नहीं लगता है।

+0

उम, आप इस तरह 'टाइमिट' का उपयोग क्यों कर रहे हैं? क्यों नहीं 'stmt =' re.search (...) ''/'stmt='r.search (...)' 'और' setup.com 'में' re.compile 'जोड़ें? – delnan

+2

फैंसी 'functools.lru_cache' यहां मुद्दा है, यह कैशिंग परिवर्तन है जिसके बाद आप हैं। यह भी देखें http://bugs.python.org/issue16389 – mmgp

+0

@ डेलनान: मैं चाहता था कि रेगेक्स का संकलन समय का हिस्सा बन जाए। –

उत्तर

24

कोड बदल गया है।

पायथन 2.7 में, कैश एक साधारण शब्दकोश है; यदि _MAXCACHE से अधिक आइटम इसमें संग्रहीत हैं, तो एक नया आइटम संग्रहीत करने से पहले पूरे कैश को साफ़ कर दिया जाता है। एक कैश लुकअप केवल एक साधारण कुंजी का निर्माण करता है और शब्दकोश का परीक्षण करता है, 2.7 implementation of _compile()

पायथन 3.x में, कैश को @functools.lru_cache(maxsize=500, typed=True) decorator द्वारा प्रतिस्थापित किया गया है। यह सजावटी अधिक अधिक काम करता है और इसमें थ्रेड-लॉक शामिल होता है, कैश एलआरयू कतार समायोजित करता है और कैश आंकड़ों को बनाए रखता है (re._compile.cache_info() के माध्यम से सुलभ)। 3.3 implementation of _compile() और functools.lru_cache() देखें।

अन्य ने एक ही मंदी देखी है, और पाइथन बगट्रैकर में issue 16389 दायर किया है। मैं उम्मीद करता हूं कि 3.4 बहुत तेज हो जाएगा; या तो lru_cache कार्यान्वयन में सुधार हुआ है या re मॉड्यूल फिर से एक कस्टम कैश में स्थानांतरित हो जाएगा।

अपडेट: revision 4b4dddd670d0 के साथ कैश परिवर्तन वापस 3.1 में पाए गए सरल संस्करण पर वापस कर दिया गया है। पायथन संस्करण 3.2.4 और 3.3.1 में संशोधन शामिल है।

+0

हुह। धन्यवाद। मुझे आश्चर्य हुआ कि क्यों strptx में regexps के लिए कैश lru_cache का उपयोग नहीं करता है। मुझे उम्मीद है कि lru_cache में सुधार किया जा सकता है क्योंकि सिद्धांत में पोंछना और फिर से शुरू करने से बेहतर है। –

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

  • कोई संबंधित समस्या नहीं^_^