2011-07-19 10 views
13

मेरे पास फ्लोट नंबर के रूप में डेटा की कई टेक्स्ट फ़ाइलें हैं। मैं सी ++ में उन्हें पढ़ने का सबसे तेज़ तरीका ढूंढ रहा हूं। यदि फ़ाइल सबसे तेज़ है तो मैं फ़ाइल को बाइनरी में बदल सकता हूं।इनपुट फ़ाइलों को पढ़ने, सबसे तेज़ तरीका संभव है?

यह अच्छा होगा अगर आप मुझे संकेत दे सकें या मुझे पूर्ण स्पष्टीकरण वाली वेबसाइट पर संदर्भित कर सकें। मुझे नहीं पता कि कोई पुस्तकालय है जो काम तेजी से करता है। भले ही कोई ओपन सोर्स सॉफ़्टवेयर है जो काम करता है, यह सहायक होगा।

+2

कृपया सी ++ प्रश्नों को 'सी' के रूप में टैग न करें। यह सिर्फ कष्टप्रद है। –

उत्तर

24

एक बाइनरी फ़ाइल होने का सबसे तेज़ विकल्प है। न केवल आप इसे एक ही ऑपरेशन में कच्चे istream::read के साथ सीधे सरणी में पढ़ सकते हैं (जो बहुत तेज़ है), लेकिन यदि आपका ओएस इसका समर्थन करता है तो आप स्मृति में फ़ाइल को भी मैप कर सकते हैं; आप POSIX सिस्टम पर open/mmap का उपयोग कर सकते हैं, CreateFile/CreateFileMapping/MapViewOfFile विंडोज पर, या यहां तक ​​कि बूस्ट क्रॉस-प्लेटफ़ॉर्म समाधान (धन्यवाद @ कोरी नेल्सन इसे इंगित करने के लिए)।

त्वरित & गंदा उदाहरण, फ़ाइल संभालने कुछ float रों के कच्चे प्रतिनिधित्व शामिल हैं:

"सामान्य" पढ़ें:

#include <boost/interprocess/file_mapping.hpp> 
#include <boost/interprocess/mapped_region.hpp> 

using boost::interprocess; 

// .... 

// Create the file mapping 
file_mapping fm("input.dat", read_only); 
// Map the file in memory 
mapped_region region(fm, read_only); 
// Get the address where the file has been mapped 
float * addr = (float *)region.get_address(); 
std::size_t elements = region.get_size()/sizeof(float); 
+5

[बूस्ट इंटरप्रोसेस] (http://www.boost.org/doc/libs/1_47_0/doc/html/interprocess/sharedmemorybetweenprocesses.html#interprocess.sharedmemorybetweenprocesses.mapped_file) क्रॉस-प्लेटफ़ॉर्म मेमोरी-मैप की गई फ़ाइलों की आपूर्ति करता है। –

+0

@ कोररी: ओह, अच्छा, यह नहीं पता था कि बूस्ट को भी वह मिला। –

+0

मेमोरी मैपिंग बहुत तेजी से होने जा रही है अगर फ़ाइल पहले ही कैश हो चुकी है। यदि नहीं, तो 'पढ़ा' इसे हरा देगा। –

5

आपका टोंटी:

#include <fstream> 
#include <vector> 

// ... 

// Open the stream 
std::ifstream is("input.dat"); 
// Determine the file length 
is.seekg(0, std:ios_base::end); 
std::size_t size=is.tellg(); 
is.seekg(0, std::ios_base::beg); 
// Create a vector to store the data 
std::vector<float> v(size/sizeof(float)); 
// Load the data 
is.read((char*) &v[0], size); 
// Close the file 
is.close(); 
साझा स्मृति के साथ

आई/ओ में है आप प्रोग्राम को कम से कम I/O कॉल में स्मृति में जितना अधिक डेटा पढ़ना चाहते हैं। उदाहरण के लिए एक fread के साथ 256 नंबर पढ़ना एक नंबर के 256 fread से तेज़ है।

यदि आप कर सकते हैं, तो लक्ष्य प्लेटफ़ॉर्म के आंतरिक फ़्लोटिंग पॉइंट प्रस्तुति, या कम से कम अपने प्रोग्राम के प्रतिनिधित्व से मेल खाने के लिए डेटा फ़ाइल स्वरूपित करें। यह आंतरिक प्रतिनिधित्व के लिए पाठपरक प्रतिनिधित्व का अनुवाद करने के ऊपरी हिस्से को कम कर देता है।

ओएस बाईपास करें और यदि संभव हो तो फ़ाइल डेटा में पढ़ने के लिए डीएमए नियंत्रक का उपयोग करें। डीएमए चिप प्रोसेसर के कंधों से स्मृति में डेटा पढ़ने का बोझ लेता है।

आपको डेटा फ़ाइल कॉम्पैक्ट करें। डेटा फ़ाइल डिस्क पर क्षेत्रों के एक संगत सेट में होना चाहता है। यह भौतिक platters पर विभिन्न क्षेत्रों की तलाश में बिताए गए समय की मात्रा को कम करेगा।

क्या आप डिस्क संसाधन और प्रोसेसर पर विशेष नियंत्रण मांगते हैं। अन्य सभी महत्वपूर्ण कार्यों को अवरुद्ध करें; अपने कार्यक्रम के निष्पादन की प्राथमिकता बढ़ाएं।

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

मल्टी-थ्रेड। डेटा में पढ़ने के लिए एक थ्रेड बनाएं और बफर खाली नहीं होने पर प्रसंस्करण कार्य को अलर्ट करें।

इन्हें आपको थोड़ी देर व्यस्त रखना चाहिए। अन्य सभी अनुकूलन के परिणामस्वरूप नगण्य प्रदर्शन लाभ होगा। (जैसे हार्ड ड्राइव नियंत्रक को सीधे आपके बफर में स्थानांतरित करने के लिए एक्सेस करना।)

+0

दिलचस्प ..... – tomasz

+1

ओपी में एक टेक्स्ट फ़ाइल है। स्पीडअप # 2, उस पाठ फ़ाइल को बाइनरी में कनवर्ट करना, चीजों को तेजी से गति देने जा रहा है। उस पर # 1 का पालन करें, जितना हो सके उतना पढ़ें। इसके बाद सबकुछ ग्रेवी है। –

2

संकलन मोड पर एक और ध्यान। मैंने 1 एम लाइनों के साथ एक फ़ाइल को पार्स करने का प्रयास किया है। डीबग मोड ने डेटा को पार्स करने के लिए 50secs का उपभोग किया और मेरे कंटेनर में शामिल किया। रिलीज मोड कम से कम दस गुना तेजी से खपत, लगभग 4secs। डेटा नीचे 2 डी अंक (,) के रूप में डेटा पार्स करने के लिए istringstream का उपयोग करने से पहले पूरी फ़ाइल को पढ़ने के लिए है।

vector <float> in_data; 
string raw_data; 

ifstream ifs; 
ifs.open(_file_in.c_str(), ios::binary); 
ifs.seekg(0, ios::end); 
long length = ifs.tellg(); 
ifs.seekg(0, ios::beg); 
char * buffer; 
buffer = new char[length]; 
ifs.read(buffer, length); 
raw_data = buffer; 
ifs.close(); 
delete[]buffer; 
cout << "Size: " << raw_data.length()/1024/1024.0 << "Mb" << endl; 
istringstream _sstr(raw_data); 
string _line; 

while (getline(_sstr, _line)){ 
    istringstream _ss(_line); 
    vector <float> record; 
    //maybe using boost/Tokenizer is a good idea ... 
    while (_ss) 
    { 
     string s; 
     if (!getline(_ss, s, ',')) break; 
     record.push_back(atof(s.c_str())); 
    } 
    in_data.push_back(record[0]); 
} 
संबंधित मुद्दे