2010-03-18 11 views

उत्तर

38

बिल्कुल। एक Matcher प्रीकंपिल्ड रेगेक्सपी पर बनाया गया है, जबकि String.matches को हर बार निष्पादित होने पर regexp को पुन: संकलित करना होगा, इसलिए यह कोड की उस पंक्ति को जितनी अधिक बार चलाएगा उतना अधिक अपमानजनक हो जाता है।

5

String.matches आंतरिक रूप से Pattern.matches(regex, str) पर कॉल करता है। इसके साथ समस्या यह है कि हर बार जब आप इसे कॉल करते हैं तो आप पैटर्न को पुन: संकलित करते हैं, जिसके लिए कुछ संसाधन खर्च होते हैं।

अपने पैटर्न को एक बार संकलित करना बेहतर है, फिर अपने इच्छित स्ट्रिंग्स के खिलाफ मिलान करने का प्रयास करें। मैं व्यक्तिगत रूप से एक पैटर्न पैटर्न का उपयोग करता हूं जिसमें मेरे ऐप में मेरे सभी पैटर्न को अंतिम और स्थैतिक

+2

"मैं व्यक्तिगत रूप से एक पैटर्न पैटर्न का उपयोग करता हूं जिसमें मेरे ऐप में मेरे सभी पैटर्न को अंतिम और स्थैतिक घोषित किया जाता है।" पैटर्न को कक्षाओं या विधियों में रखना बेहतर है जहां वास्तव में उनका उपयोग किया जाता है। इस तरह, कोड जो एक साथ बदलता है उसे एक साथ पैक किया जाता है। [सामान्य क्लोजर सिद्धांत] देखें (http://c2.com/cgi/wiki?CommonClosurePrinciple)। –

+1

वास्तव में मैं आपसे सहमत हूं। मेरी राय 4 साल में बदल गई है :-) – chburd

23

स्ट्रिंग.मैट्स आंतरिक रूप से Matcher.matches को प्रस्तुत करता है।

public boolean matches(String regex) { 
    return Pattern.matches(regex, this); 
} 

public static boolean matches(String regex, CharSequence input) { 
    Pattern p = Pattern.compile(regex); 
    Matcher m = p.matcher(input); 
    return m.matches(); 
} 

आप पैटर्न वस्तु पुन: उपयोग कर रहे हैं तो वहाँ कुछ प्रदर्शन लाभ होगा। पैटर्न/मैचर का उपयोग करते समय आप group अपने नियमित अभिव्यक्तियों को प्राप्त कर सकते हैं और मिलान करने वाले हिस्सों को प्राप्त कर सकते हैं।

नीचे की रेखा यह है कि यदि आपके पास एक रेगेक्स है जिसे आप केवल एक बार उपयोग करेंगे और आपको मिलान करने वाले हिस्सों को पाने के लिए अपनी स्ट्रिंग को पार्स करने की आवश्यकता नहीं है तो या तो उपयोग करें। लेकिन यदि आप एकाधिक तारों के खिलाफ एक ही रेगेक्स का उपयोग करने जा रहे हैं या आपको रेगेक्स के आधार पर स्ट्रिंग के कुछ हिस्सों की आवश्यकता है तो पैटर्न बनाएं और इसका उपयोग करके मैचर प्राप्त करें।

8

जिज्ञासा से मैं समय मतभेदों पर इस छोटे से परीक्षण किया। पूर्व-संकलित पैटर्न का उपयोग कर को बाहर निकालना String.matches विधि का उपयोग करने से 5 गुना तेज से अधिक है।

import java.util.regex.Pattern; 

/** 
* @author Rajind Ruparathna 
*/ 
public class MatchesTest { 
    public static void main(String Args[]) { 
     String first = "@\\{message.headers\\.?([^\\}]*)\\}"; 
     String second = "@\\{message.headers.wolla\\}"; 
     long start, end, total; 
     float avg; 
     int NUM_OF_ITERATIONS = 100; 

     Pattern pattern = Pattern.compile(first); 

     total = 0; 
     start = 0; 
     end = 0; 
     avg = 0; 

     for (int i=0; i< NUM_OF_ITERATIONS; i++) { 
      start = System.nanoTime(); 
      pattern.matcher(second).matches(); 
      end = System.nanoTime(); 
      total = total + (end - start); 
     } 
     avg = total/NUM_OF_ITERATIONS; 
     System.out.println("Duration pre compiled: " + avg); 

     total = 0; 
     start = 0; 
     end = 0; 
     avg = 0; 

     for (int i=0; i< NUM_OF_ITERATIONS; i++) { 
      start = System.nanoTime(); 
      first.matches(second); 
      end = System.nanoTime(); 
      total = total + (end - start); 
     } 
     avg = total/NUM_OF_ITERATIONS; 
     System.out.println("In place compiled: " + avg); 
    } 
} 

आउटपुट (नैनोसेकंड):

अवधि संकलित पूर्व: 4505,0

जगह में संकलित: 44960,0

पी.एस. यह परीक्षण एक त्वरित और गंदे परीक्षण है और प्रदर्शन बेंचमार्किंग प्रथाओं के अनुसार नहीं हो सकता है। यदि आप अत्यधिक सटीक परिणाम प्राप्त करना चाहते हैं तो कृपया एक माइक्रो बेंचमार्किंग टूल का उपयोग करें।

+1

यह वह बेंचमार्क है जिसे मैं ढूंढ रहा था - धन्यवाद! – Tadhg

0

Pattern.compile पैटर्न को संकलित करता है ताकि जब आप metcher.matches निष्पादित करते हैं, पैटर्न को बार-बार संकलित नहीं किया जाता है। Pattern.compile पूर्व इसे संकलित करता है। हालांकि, अगर आप string.matches का उपयोग करते हैं, तो यह हर बार जब आप इस लाइन को निष्पादित करते हैं तो पैटर्न को संकलित करता है। तो, Pattern.compile का उपयोग करना बेहतर है।

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