Effective STL Terms 29

zhaozj2021-02-11  189

Terms 29: Consider using ISTREAMBUF_ITERATOR when you need a character input

Suppose we have to copy a text file into a string object. It seems that it can be done with a very reasonable method:

IFStream InputFile ("InterestingData.txt");

String FileData ((iStream_Iterator ), // Read InputFile

iStream_iterator ()); // filedata;

// It is not very correct to see below

/ / Warning about this grammar

// See Terms 6

Soon you will find that this method cannot copy spaces in the file to the string. That is because iStream_iterators uses the Operator << function to make true read, and the Operator << function is ignored by default.

If you want to keep the space, what you want is to overwrite the default. Just clear the Skipws flag of the input stream:

IFStream InputFile ("InterestingData.txt");

InputFile.unset (iOS :: Skipws); // Close InputFile

/ / Ignore space sign

String FileData (ISTREAM_ITERATOR (InputFile), istream_iterator ());

All characters in InputFile are now copied to FileData.

Hey, you will find that their copy speed is not as fast as you think. The Operator << function of iStream_iterators relies on formatting, which means that they must do a lot of work every time you call. They must establish and destroy the SENTRY objects (for each Operator << Call for special iostream objects), they must check streams that may affect their behavior (such as Skipws), they must be comprehensive Read the error check, and if they encounter problems, they must check the abnormal mask of the stream to determine whether to throw an exception. If you format your input, those are important activities, but if you need it just from the input stream, it is over.

A more efficient method is one of the best secret weapons using STL: istreambuf_iterators. You can use iStreamBuf_iterator like ISTREAM_ITERATOR, but iStream_iterator object uses Operator << to read a single character from the input stream. iStreamBuf_iterator The object enters the stream buffer and reads the next character directly. (More specifically, an istreamBuf_iterator reads from an ISTREAM S will call s.rdbuf () -> sgetc () to read the next character.) Change our file reading code to use IstreamBuf_iterator is quite simple, most Visual Basic programmers can do it within two attempts:

IFStream InputFile ("InterestingData.txt");

String FileData ((istreambuf_iterator ),

iStreamBuf_iterator ());

Note that "Unset" Skipws flag is not required, and iStreamBuf_iterator does not ignore any characters. They only grasp the next character of the flow buffer. Compared to ISTREAM_ITERATOR, they caught faster - 40% faster in my simple test, if your results don't have to be surprised. If you pass by, the speed advantage is increasing, it doesn't have to be strange, because iStreamBuf_iterator exists in an uncommonly accessed corner of STL, so that there is still no spending lot to optimize. For example, in one of the implementations I have used, iStreamBuf_iterator is only about 5% faster than ISTREAM_ITERATOR in my main test. That implementation apparently there are many rooms to optimize their ISTREAMBUF_ITERATOR implementation. If you need a character to read a stream, you don't need to format the power of the input, you care about how much time it takes to read the current, and the obvious performance improvement is mostly used for each iterator. The cost of three characters is weak. For a format one character input, you should always consider using iStreamBuf_iterator.

When you understand it, you should also consider the work of the OstreamBuf_iterator for the corresponding unformatted one character output. They don't have Ostream_iterator overhead (and flexibility), so they are usually better.

转载请注明原文地址:https://www.9cbs.com/read-4764.html

New Post(0)