Domanda

I'm using a small piece of code that generates PDF files, which I found on the internet, and tried to (softly) optimize it as the creation of a file would take ages. After profiling, I narrowed it down to the following piece of code :

std::ostringstream tmp;
tmp << std::hex << std::uppercase << std::setfill('0') <<
    std::setw(2) << r << " " <<
    std::setw(2) << g << " " <<
    std::setw(2) << b;

out << tmp.str();

found in a tight loop, with out being a ostringstream that contains basically the whole PDF content before it's written into the file. I found that tmp.str() was the line that took the most time in that loop, and saw when looking up the C++ reference that str() would return a copy of the stream's underlying string.

Then, I thought removing that copy and using directly out would be faster. So I dumped tmp and directly did:

out << std::hex << std::uppercase << std::setfill('0') <<
    std::setw(2) << r << " " <<
    std::setw(2) << g << " " <<
    std::setw(2) << b;

But now, the PDF file generated is considered "broken" and can't be opened by a PDF reader, while the previous one could be. I created a PDF with both methods (with the tmp stream and without) to compare the lines output, but found no obvious differences...

Then, what could be the reason for this ? Is there a reason to use that temporary stream ? Is it, and why could it be different than directly using the out stream ?

I thought it could be something related either to newlines or to the manipulators, but couldn't find anything significant on these

È stato utile?

Soluzione

The thing to consider is that the io manipulators (for example std::hex) are persistent from that point forward on the stream.

So once you insert the std::hex manipulator, all integral values are printed out in hex format from this point forward.

Your previous approach did not have this problem as the manipulator was on a transient stream. You could try inserting the std::dec manipulator once you are done...

Pulling up from Jan Hudec's comment, Boost IO State Savers are the nice way forward to handle this cleanly.

Altri suggerimenti

Another little difference: If the formatted output to the std::ostringstream fails the destination out is not affected.

(Nim's answer describes the actual problem)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top