2009-04-10 10 views
10

मैं वर्तमान में split() का उपयोग कर उस फ़ाइल को स्कैन करने के लिए उपयोग कर रहा हूं जहां प्रत्येक पंक्ति में '~' द्वारा सीमित तारों की संख्या होती है। मैंने कहीं पढ़ा है कि Scanner एक लंबी फ़ाइल के साथ बेहतर काम कर सकता है, प्रदर्शन के अनुसार, इसलिए मैंने इसे जांचने के बारे में सोचा।जावा स्कैनर बनाम स्ट्रिंग.split() बनाम स्ट्रिंगटोकनाइज़र; मुझे किस का उपयोग करना चाहिए?

मेरा सवाल है: क्या मुझे Scanner के दो उदाहरण बनाना होगा? यही है, एक लाइन को पढ़ने के लिए और एक डीलिमीटर के लिए टोकन प्राप्त करने के लिए लाइन पर आधारित एक और? अगर मुझे ऐसा करना है, तो मुझे संदेह है कि मुझे इसका उपयोग करने से कोई फायदा होगा। शायद मैं यहाँ कुछ याद कर रहा हूँ?

उत्तर

3

मैं कहूंगा कि split() सबसे तेज़ है, और संभवतः आप जो भी कर रहे हैं उसके लिए पर्याप्त है। हालांकि यह scanner से कम लचीला है। StringTokenizer बहिष्कृत है और केवल पिछड़ा संगतता के लिए उपलब्ध है, इसलिए इसका उपयोग न करें।

संपादित करें: आप हमेशा यह देखने के लिए दोनों कार्यान्वयन का परीक्षण कर सकते हैं कि कौन सा तेज़ है। अगर मैं scannersplit() से तेज़ हो सकता हूं तो मैं उत्सुक हूं। स्प्लिट किसी दिए गए आकार VS Scanner के लिए तेज़ हो सकता है, लेकिन मैं इसके बारे में निश्चित नहीं हो सकता।

+0

मैं मानता हूं कि स्ट्रिंगटोकनाइज़र संभवतः बहिष्कृत है, लेकिन मुझे इसे j2se5 और java6 के लिए बहिष्कृत कक्षाओं की सूची में नहीं मिला। क्यूं कर? – gedevan

+0

स्ट्रिंगटोकोजियर को बहिष्कृत नहीं किया गया है ... – Jon

+0

आप सही हैं, यह नहीं है।लेकिन एपीआई से: स्ट्रिंगटोकनाइज़र एक विरासत वर्ग है जो संगतता कारणों के लिए बनाए रखा गया है हालांकि इसका उपयोग नए कोड में निराश है। यह अनुशंसा की जाती है कि इस कार्यक्षमता की तलाश करने वाले किसी भी व्यक्ति को स्ट्रिंग या java.util.regex पैकेज की विभाजन विधि का उपयोग करें। – CookieOfFortune

6

प्रसंस्करण लाइन के लिए आप स्कैनर का उपयोग कर सकते हैं और प्रत्येक पंक्ति से टोकन प्राप्त करने के लिए आप विभाजन का उपयोग कर सकते हैं।

Scanner scanner = new Scanner(new File(loc)); 
try { 
    while (scanner.hasNextLine()){ 
     String[] tokens = scanner.nextLine().split("~"); 
     // do the processing for tokens here 
    } 
} 
finally { 
    scanner.close(); 
} 
5

आप, hasNext()/next() साथ प्रत्येक पंक्ति पर टोकन के माध्यम से पुनरावृति जबकि अभी भी hasNextLine()/nextLine() का उपयोग कर लाइनों के लिए खुद के माध्यम से पुनरावृति करने के लिए जाने के लिए useDelimiter("~") विधि का उपयोग कर सकते हैं।

संपादित करें: रेगुलर एक्सप्रेशन आप एक प्रदर्शन की तुलना करने के लिए जा रहे हैं, तो आप चाहिए पूर्व संकलन जब आप विभाजन() परीक्षण करना:

Pattern splitRegex = Pattern.compile("~"); 
while ((line = bufferedReader.readLine()) != null) 
{ 
    String[] tokens = splitRegex.split(line); 
    // etc. 
} 

आप String#split(String regex) उपयोग करते हैं, regex फिर कंपाइल किया जाएगा हर बार। (स्कैनर स्वचालित रूप से उन सभी regexes को कैश करता है जब यह उन्हें संकलित करता है।) यदि आप ऐसा करते हैं, तो मैं प्रदर्शन में बहुत अंतर देखने की उम्मीद नहीं करता।

2

आपको वास्तव में यहां एक रेगेक्स की आवश्यकता नहीं है, क्योंकि आप एक निश्चित स्ट्रिंग पर विभाजित हैं। अपाचे StringUtilssplit सादे तारों पर विभाजित होता है।

उच्च मात्रा विभाजन के लिए, जहां फ़ाइल आईओ कहने के बजाय विभाजन बाधा है, मुझे यह String.split() से 10 गुना तेजी से पाया गया है। हालांकि, मैंने इसे एक संकलित रेगेक्स के खिलाफ परीक्षण नहीं किया।

अमरूद में एक स्प्लिटर भी है, जिसे एक और ओओ तरीके से लागू किया गया है, लेकिन मुझे लगता है कि यह उच्च मात्रा के विभाजन के लिए स्ट्रिंगयूटिल की तुलना में काफी धीमी थी।

8

क्या इन्हें एक थ्रेडेड मॉडल में चारों ओर कुछ मीट्रिक किया गया था और यहां मेरे परिणाम हैं।

 
~~~~~~~~~~~~~~~~~~Time Metrics~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
~ Tokenizer | String.Split() | while+SubString | Scanner | ScannerWithCompiledPattern ~ 
~ 4.0 ms |  5.1 ms  |  1.2 ms  |  0.5 ms |    0.1 ms   ~ 
~ 4.4 ms |  4.8 ms  |  1.1 ms  |  0.1 ms |    0.1 ms   ~ 
~ 3.5 ms |  4.7 ms  |  1.2 ms  |  0.1 ms |    0.1 ms   ~ 
~ 3.5 ms |  4.7 ms  |  1.1 ms  |  0.1 ms |    0.1 ms   ~ 
~ 3.5 ms |  4.7 ms  |  1.1 ms  |  0.1 ms |    0.1 ms   ~ 
____________________________________________________________________________________________________________ 

बाहर आ गया है कि स्कैनर सर्वश्रेष्ठ प्रदर्शन देता है, अब इसे बहुप्रचारित मोड पर मूल्यांकन करने की आवश्यकता है! मेरे सीनियर में से एक का कहना है कि टोकेनाइज़र एक सीपीयू स्पाइक देता है और String.split नहीं करता है।