Opened 16 years ago

Closed 15 years ago

#817 closed Bugs (fixed)

Performance problem in iostreams

Reported by: nobody Owned by: Jonathan Turkanis
Milestone: Component: iostreams
Version: None Severity: Problem
Keywords: Cc:

Description

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<typename T, typename Tr, typename Alloc, typename Mode>
typename indirect_streambuf<T, Tr, Alloc, Mode>::pos_type
indirect_streambuf<T, Tr, Alloc, Mode>::seek_impl
    (stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which)
{
    if (pptr() != 0)
        this->BOOST_IOSTREAMS_PUBSYNC(); // sync() confuses VisualAge 6.
    if (way == BOOST_IOS::cur && gptr())
        off -= static_cast<off_type>(egptr() - gptr());
    setg(0, 0, 0);
    setp(0, 0);
    return obj().seek(off, way, which, next_);
}

jerker.ohman@umetrics.com

Change History (3)

comment:1 by gmsb, 16 years ago

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<typename T, typename Tr, typename Alloc, typename Mode>
typename indirect_streambuf<T, Tr, Alloc, Mode>::pos_type
indirect_streambuf<T, Tr, Alloc, Mode>::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
      && way == BOOST_IOS::cur && which == BOOST_IOS::in      // for a relative seek
      && eback() - gptr() <= off && off <= 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<stream_offset>(egptr() - gptr()) );
    }
    //XX- GMSB 20-Feb-2006 Performance fix for tellg() and small seekg()
    if (pptr() != 0) 
        this->BOOST_IOSTREAMS_PUBSYNC(); // sync() confuses VisualAge 6.
    if (way == BOOST_IOS::cur && gptr())
        off -= static_cast<off_type>(egptr() - gptr());
    setg(0, 0, 0);
    setp(0, 0);
    return obj().seek(off, way, which, next_);
}

comment:2 by Daryle Walker, 15 years ago

Component: Noneiostreams
Severity: Problem

comment:3 by Jonathan Turkanis, 15 years ago

Resolution: Nonefixed
Status: assignedclosed

I applied the patch from GMSB in [42367] and [42638] in branches/iostreams_dev, to be merged with trunk shortly.

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.

Note: See TracTickets for help on using tickets.