From 598a1b4dd1a6cc1bfe689a6931af9e6aa47134e1 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Thu, 14 Mar 2019 13:43:17 +0100 Subject: [PATCH 1/1] Avoid third seek operation in `Seek::stream_len` when possible --- src/libstd/io/mod.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 99bb24f54dd..9edda304bb9 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1332,10 +1332,11 @@ pub trait Seek { /// Returns the length of this stream (in bytes). /// - /// This method is implemented using three seek operations. If this method - /// returns successfully, the seek position is unchanged (i.e. the position - /// before calling this method is the same as afterwards). However, if this - /// method returns an error, the seek position is undefined. + /// This method is implemented using up to three seek operations. If this + /// method returns successfully, the seek position is unchanged (i.e. the + /// position before calling this method is the same as afterwards). + /// However, if this method returns an error, the seek position is + /// undefined. /// /// If you need to obtain the length of *many* streams and you don't care /// about the seek position afterwards, you can reduce the number of seek @@ -1368,7 +1369,13 @@ pub trait Seek { fn stream_len(&mut self) -> Result { let old_pos = self.stream_position()?; let len = self.seek(SeekFrom::End(0))?; - self.seek(SeekFrom::Start(old_pos))?; + + // Avoid seeking a third time when we were already at the end of the + // stream. The branch is usually way cheaper than a seek operation. + if old_pos != len { + self.seek(SeekFrom::Start(old_pos))?; + } + Ok(len) } -- 2.44.0