Skip to content

Commit 598a1b4

Browse files
Avoid third seek operation in Seek::stream_len when possible
1 parent e8ee00a commit 598a1b4

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

src/libstd/io/mod.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -1332,10 +1332,11 @@ pub trait Seek {
13321332

13331333
/// Returns the length of this stream (in bytes).
13341334
///
1335-
/// This method is implemented using three seek operations. If this method
1336-
/// returns successfully, the seek position is unchanged (i.e. the position
1337-
/// before calling this method is the same as afterwards). However, if this
1338-
/// method returns an error, the seek position is undefined.
1335+
/// This method is implemented using up to three seek operations. If this
1336+
/// method returns successfully, the seek position is unchanged (i.e. the
1337+
/// position before calling this method is the same as afterwards).
1338+
/// However, if this method returns an error, the seek position is
1339+
/// undefined.
13391340
///
13401341
/// If you need to obtain the length of *many* streams and you don't care
13411342
/// about the seek position afterwards, you can reduce the number of seek
@@ -1368,7 +1369,13 @@ pub trait Seek {
13681369
fn stream_len(&mut self) -> Result<u64> {
13691370
let old_pos = self.stream_position()?;
13701371
let len = self.seek(SeekFrom::End(0))?;
1371-
self.seek(SeekFrom::Start(old_pos))?;
1372+
1373+
// Avoid seeking a third time when we were already at the end of the
1374+
// stream. The branch is usually way cheaper than a seek operation.
1375+
if old_pos != len {
1376+
self.seek(SeekFrom::Start(old_pos))?;
1377+
}
1378+
13721379
Ok(len)
13731380
}
13741381

0 commit comments

Comments
 (0)