वेक्टर <स्ट्रिंग> सी ++ में तेज़ लोड के लिए फ़ाइल में ज्ञात अधिकतम लंबाई की स्ट्रिंग को स्टोर करने का सबसे अच्छा तरीका

I've got big amount of text data which I need to save to file for next reprocessing. These data are stored in table like vector< vector< string > > - every record (vector) has same number of attributes(vector). So, going through the vector I can find the max length of every attribute in table and count of records. Now I have to write these data to file (can be binary) in that way that I will be able to load them back into vector< vector< string > > very fast. It doesn't matter how much time will writing take but I need reading to vector implement in the fastest way.

तथ्य यह है कि डेटा को "रिकॉर्ड द्वारा रिकॉर्ड" संसाधित किया जाएगा, पूरी फ़ाइल स्मृति में लोड नहीं हो सकती है। लेकिन तेजी से पढ़ने के लिए मैं बफर 256 एमबी या 512 एमबी का उपयोग करना चाहता हूं।

तो अब के लिए मैंने इसे इस तरह कार्यान्वित किया:

  1. डेटा दो फाइलों में संग्रहीत किया जाता है - विवरण फ़ाइल और डेटा फ़ाइल। विवरण फ़ाइल में रिकॉर्ड्स की गणना, गुणों की गिनती और प्रत्येक विशेषता की अधिकतम लंबाई शामिल है। डेटा फ़ाइल वर्णों की बाइनरी फ़ाइल है। कोई मूल्य या रिकॉर्ड विभाजक नहीं हैं, केवल मूल्य हैं। कंक्रीट विशेषता में प्रत्येक मान की लंबाई समान होती है, इसलिए यदि कुछ मान की अधिकतम लंबाई की तुलना में छोटी लंबाई होती है, तो शेष वर्ण शून्य वर्ण '\ 0' होते हैं।

  2. फिर मैंने std :: fread के साथ चार सरणी बफर (256 एमबी या 512 एमबी) में फ़ाइल का हिस्सा पढ़ा। जब एप्लिकेशन फ़ंक्शन वेक्टर getNext() को कॉल करता है, तो मैंने बफर से वर्णों का हिस्सा पढ़ा है (क्योंकि मुझे प्रत्येक विशेषता की लंबाई पता है) और वेक्टर बनाने के लिए प्रत्येक चार को कंक्रीट स्ट्रिंग में संलग्न करें।

लेकिन, इस तरह से मेरे उद्देश्य के लिए इतना तेज़ नहीं लगता है जब मुझे बफर से वेक्टर तक लूप में रिकॉर्ड की बड़ी संख्या की आवश्यकता होती है। इस समस्या को पूरा करने का एक और बेहतर तरीका है?

कोड का यह भाग बफर से मूल्यों को वर्णों में पार्स कर रहा है:

string value;
vector record;
int pos = bfrIndex();//returns current position in buffer. position of values of next record
for(unsigned int i = 0; i < d.colSize.size(); i++) {//d.colSize is vector of every attribute
    value.clear();
    value.reserve(d.colSize[i]);
    for(unsigned int j = pos; j < pos + d.colSize[i]; j++) {
        if (buffer[j] == '\0') break;
        value += buffer[j];
    }
    record.push_back(value);
    pos += d.colSize[i];//set position in buffer to next value
}
return record;
0

2 उत्तर

vector > is a 3d character "cube" where every dimension vary in size along the others. Unless you are able to predict each "size", you risk to read one-by one and reallocate every time.

Fast reading happens when you can "load up" the data all in once, and than define how to split. The data structure will probably be a single string, and a vector > where range is a std::pair.

समस्या यह है कि आप स्ट्रिंग्स को एक साथ कड़े होने में हेरफेर नहीं कर सकते हैं।

A second chance is maintain the dynamic nature of vector >,but store the dataso that each "size" can be read before the data tehnselves, so that you can resize the vectos and then read the content into its componets.

छद्म कोड में:

template
void save(const Container& c, const stream& s)
{ s.write(c.size()); for(auto& e: c) save(e,s) }

template
void load(Container& c, const stream& s)
{ 
   int sz=0; s.read(c.size()); c.resize(sz);
   for(auto& i:c) load(i,s);
}

बेशक, स्ट्रिंग-एस के लिए विशेष ताकि एक स्ट्रिंग को सहेजने/लोड करने से वास्तव में अपने स्वयं के वर्ण लिखते/पढ़ते हैं।

0
जोड़ा

I'd consider a binary approach that used the method employed in Doom's .wad files. I.e a directory with length & file offsets of each resource, followed by the resources themselves. With a small amount of overhead for the directory, you get instant knowledge of both where to find each string and how long they each are.

0
जोड़ा