Boost C++ Libraries: Ticket #817: Performance problem in iostreams https://svn.boost.org/trac10/ticket/817 <pre class="wiki"> iostreams dumps its internal buffers every time seekg or tellg is called even if the seek is to the current position. The following function should check if the seek position is within the buffer and, if so, adjust the buffers. template&lt;typename T, typename Tr, typename Alloc, typename Mode&gt; typename indirect_streambuf&lt;T, Tr, Alloc, Mode&gt;::pos_type indirect_streambuf&lt;T, Tr, Alloc, Mode&gt;::seek_impl (stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) { if (pptr() != 0) this-&gt;BOOST_IOSTREAMS_PUBSYNC(); // sync() confuses VisualAge 6. if (way == BOOST_IOS::cur &amp;&amp; gptr()) off -= static_cast&lt;off_type&gt;(egptr() - gptr()); setg(0, 0, 0); setp(0, 0); return obj().seek(off, way, which, next_); } jerker.ohman@umetrics.com </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/817 Trac 1.4.3 gmsb Mon, 29 Jan 2007 16:01:09 GMT <link>https://svn.boost.org/trac10/ticket/817#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/817#comment:1</guid> <description> <pre class="wiki">Logged In: YES user_id=271167 Originator: NO I used to have exactly the performance problems described. Here is the patch I've been using. Hopefully Jonathan Turkanis can review whether this patch has undesirable side-effects. template&lt;typename T, typename Tr, typename Alloc, typename Mode&gt; typename indirect_streambuf&lt;T, Tr, Alloc, Mode&gt;::pos_type indirect_streambuf&lt;T, Tr, Alloc, Mode&gt;::seek_impl (stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) { //XX+ GMSB 20-Feb-2006 Performance fix for tellg() and small seekg() if ( gptr() != 0 // when currently input buffered &amp;&amp; way == BOOST_IOS::cur &amp;&amp; which == BOOST_IOS::in // for a relative seek &amp;&amp; eback() - gptr() &lt;= off &amp;&amp; off &lt;= egptr() - gptr() ) // within the buffer { gbump( off ); off = 0; const pos_type pos_at_egptr = obj().seek(off, way, which, next_); return offset_to_position( position_to_offset( pos_at_egptr ) - static_cast&lt;stream_offset&gt;(egptr() - gptr()) ); } //XX- GMSB 20-Feb-2006 Performance fix for tellg() and small seekg() if (pptr() != 0) this-&gt;BOOST_IOSTREAMS_PUBSYNC(); // sync() confuses VisualAge 6. if (way == BOOST_IOS::cur &amp;&amp; gptr()) off -= static_cast&lt;off_type&gt;(egptr() - gptr()); setg(0, 0, 0); setp(0, 0); return obj().seek(off, way, which, next_); } </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Daryle Walker</dc:creator> <pubDate>Fri, 03 Aug 2007 12:20:58 GMT</pubDate> <title>component changed; severity set https://svn.boost.org/trac10/ticket/817#comment:2 https://svn.boost.org/trac10/ticket/817#comment:2 <ul> <li><strong>component</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">iostreams</span> </li> <li><strong>severity</strong> → <span class="trac-field-new">Problem</span> </li> </ul> Ticket Jonathan Turkanis Sun, 30 Dec 2007 09:57:49 GMT status, resolution changed https://svn.boost.org/trac10/ticket/817#comment:3 https://svn.boost.org/trac10/ticket/817#comment:3 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">fixed</span> </li> </ul> <p> I applied the patch from GMSB in <a class="changeset" href="https://svn.boost.org/trac10/changeset/42367" title="applied patch from ticket #817, with modifications">[42367]</a> and <a class="changeset" href="https://svn.boost.org/trac10/changeset/42638" title="[logging] - added test for formatter::file">[42638]</a> in branches/iostreams_dev, to be merged with trunk shortly. </p> <p> I changed the code slightly, to reflect the coding style of the library and to remove two unnecessary conversions. Table 88 of the C++ standard shows that a value of type off_type can be subtracted from a value of type pos_type to yield a value of type pos_type; since in the case at hand we are dealing with small offsets it is safe to convert egptr() - gptr() to off_type. </p> Ticket