का उपयोग MappedByteBuffer
(जावा में स्मृति मैप की गई फ़ाइल) की कोशिश करने के लिए, मैं एक साधारण wc -l
(पाठ फ़ाइल लाइन गिनती) डेमो लिखा है:जावा में यह "लाइन गिनती" प्रोग्राम धीमा क्यों है? MappedByteBuffer
int wordCount(String fileName) throws IOException {
FileChannel fc = new RandomAccessFile(new File(fileName), "r").getChannel();
MappedByteBuffer mem = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
int nlines = 0;
byte newline = '\n';
for(long i = 0; i < fc.size(); i++) {
if(mem.get() == newline)
nlines += 1;
}
return nlines;
}
मैं लगभग 15 एमबी (15,008,641 बाइट्स) की एक फ़ाइल पर यह कोशिश की, और 100k लाइनें। मेरे लैपटॉप पर, इसमें लगभग 13.8 sec
लगता है। यह इतना धीमा क्यों है?
पूरा वर्ग कोड यहाँ है: http://pastebin.com/hXnDvZm6
यह बारे में 28 एमएस, या 490 times faster
में चलता है: http://pastebin.com/t8PLRGMa
संदर्भ के लिए, मैं सी में एक ही विचार लिखा था।
जिज्ञासा से, मैंने जावा में आवश्यक रूप से वही एल्गोरिदम और एपीआई का उपयोग करके एक स्कैला संस्करण भी लिखा। यह 10 times faster
चलाता है, जो बताता है कि निश्चित रूप से कुछ अजीब चल रहा है।
अद्यतन: फ़ाइल ओएस द्वारा कैश की गई है, इसलिए कोई डिस्क लोडिंग समय शामिल नहीं है।
मैं बड़ी फ़ाइलों को यादृच्छिक पहुंच के लिए मेमोरी मैपिंग का उपयोग करना चाहता था जो रैम में फिट नहीं हो सकता है। यही कारण है कि मैं सिर्फ एक BufferedReader का उपयोग नहीं कर रहा हूँ।
जावा संस्करण: OpenJDK 1.8.0 मंच: लिनक्स 4.1.16 – cidermole
'MappedByteBuffer' उपयोग करने के लिए गलत बात है, अपने कार्यक्रम कुछ भी लेकिन एक सादे' BufferedReader की जरूरत नहीं है '। आप 'मैप्डबेट बफर' की किसी भी उन्नत विशेषताओं का उपयोग नहीं कर रहे हैं तो इसका उपयोग क्यों करें? –
मैं एक उत्तर टाइप कर रहा था, लेकिन सवाल बंद कर दिया गया था। आपका कोड धीमा है क्योंकि यह बाइट द्वारा बाइट पढ़ता है, और यह बहुत धीमा है। बफर द्वारा बफर पढ़ें, और प्रदर्शन नाटकीय रूप से बढ़ेगा। Https://gist.github.com/jnizet/21341d48f631b7f10bc657e560c0f2de का उपयोग करके, उदाहरण के लिए, व्यतीत समय 50493us है। बनाम 8646279us। आपके मूल संस्करण के लिए। लेकिन मैं सहमत हूं कि BufferedInputStream वैसे भी आसान होगा। –