2013-02-15 9 views
13

निम्नलिखित कोड दिया सवाल राज्यों के रूप में कारणों:जावा String.split प्रदर्शन के लिए precompiled regex में पारित

:

public class Foo 
{ 
    public static void main(String[] args) 
    { 
     String test = "Cats go meow"; 
     String[] tokens = test.split(" "); 
    } 
} 

यह संभव है इस की तर्ज पर विभाजित समारोह में कि regex precompile करने के लिए बजाय

public class Foo 
{ 
    Pattern pattern = Pattern.compile(" "); 
    public static void main(String[] args) 
    { 
     String test = "Cats go meow"; 
     String[] tokens = test.split(pattern); 
    } 
} 
+0

विभाजन ("") तेजी से (नीचे टिप्पणी देखें) –

+0

@michael_s मैं एक टिप्पणी की है, का मुकाबला करें। – Woot4Moo

उत्तर

17

हाँ, यह संभव है। साथ ही, pattern स्थिर बनाएं ताकि स्थैतिक विधि main इसे एक्सेस कर सके।

public class Foo 
{ 
    private static Pattern pattern = Pattern.compile(" "); 
    public static void main(String[] args) 
    { 
     String test = "Cats go meow"; 
     String[] tokens = pattern.split(test); 
    } 
} 

स्ट्रिंग में split विधि के लिए docs के अनुसार, आप का उपयोग स्ट्रिंग के split या पैटर्न के split, लेकिन स्ट्रिंग के split एक Pattern संकलित करता है तथा इसके split प्रणाली को बुलाती है, तो Pattern का उपयोग एक regex precompile करने के लिए कर सकते हैं।

+0

हां 'पैटर्न # विभाजन (स्ट्रिंग) 'लगभग 25% तेज है। ओरेकल द्वारा स्लाइड बेंचमार्क देखें (स्लाइड 72) https://shipilev.net/talks/joker-Oct2014-string-catechism.pdf – ruhong

3

उपयोग Pattern.split():

String[] tokens = pattern.split(test); 
+0

हम्म वास्तव में, यह पैटर्न की पूर्व-संकलन को संबोधित नहीं करता है क्योंकि यह संकलन चरण है जो "सबसे अधिक समय" – Woot4Moo

+0

@ Woot4Moo लेता है: मुझे आपकी अंतिम टिप्पणी नहीं मिलती है। एक बार आपके पास 'पैटर्न' का उदाहरण हो जाने के बाद, रेगेक्स संकलित किया गया है, और 'pattern.split()' के लिए कोई और संकलन की आवश्यकता नहीं है। – NPE

+0

मेरी गलती मैंने सोचा था कि पैटर्न को तुरंत चालू करने का एक तरीका था। – Woot4Moo

5
public class Foo 
{ 
    private static final Pattern pattern = Pattern.compile(" "); 
    public static void main(String[] args) 
    { 
     String test = "Cats go meow"; 
     String[] tokens = pattern.split(test); 
    } 
} 
+1

पैटर्न को स्थिर और अंतिम बनाने पर भी विचार करें। यह प्रत्येक उदाहरण – Rohit

3

नहीं - मुझे लगता है कि यह एक बुरा विचार होगा!

विभाजन विधि के स्रोत कोड को बारीकी से देख रहे हैं - वहाँ एक शॉर्टकट कार्यान्वित मामले में स्ट्रिंग केवल एक वर्ण की है (और एक regex-विशेष वर्ण शामिल नहीं है)

public String[] split(String regex, int limit) { 
    /* fastpath if the regex is a 
    (1)one-char String and this character is not one of the 
     RegEx's meta characters ".$|()[{^?*+\\", or 
    (2)two-char String and the first char is the backslash and 
     the second is not the ascii digit or ascii letter. 
    */ 
    char ch = 0; 
    if (((regex.value.length == 1 && 
     ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) || 

तो है - विभाजन ("") बहुत तेज़ होना चाहिए।

दूसरी तरफ रेगेक्स का उपयोग करते समय उन्हें स्थिर अंतिम सदस्य बनाना हमेशा अच्छा विचार होता है।

संपादित करें:

स्रोत कोड JDK1.7 और OpenJDK 7 String.split के लिए समान प्रतीत हो रहा है - एक नज़र अपने आप है: - और अधिक जटिल पैटर्न (1 या अधिक रिक्त स्थान के लिए Lines 2312ff.

तो उदाहरण) के लिए:

static final Pattern pSpaces = Pattern.compile("[ ]+"); 
+0

हम्म के लिए संकलन ओवरहेड को सहेज लेगा प्रतियोगिता करें कि एक समय लूप के अंदर एक String.split इस दावे को अमान्य कर देगा। काउंटर करने के लिए देखभाल? – Woot4Moo

+0

मुझे समझ में नहीं आता कि आपका क्या मतलब है - लूप के दौरान क्या? –

+0

सिर्फ इसलिए कि मेरा प्रोग्राम 'जबकि' लूप को चित्रित नहीं करता है इसका मतलब यह नहीं है कि अन्य प्रोग्रामों में उनके पास नहीं है। अगर मैंने एक पार्सर लिखा था जिसे लाइनों की एक श्रृंखला को टोकन करना था, तो 'while' लूप – Woot4Moo

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