On Apr 2, 2014, at 8:35 AM, Alex Crichton <a...@crichton.co> wrote:

> As a concrete example, I'll take the read_to_end() method on io's Reader 
> trait.
> This type must use a Vec<T> internally to read data into the vector, but it 
> will
> return a ~[T] because the contents are conceptually frozen after they have 
> been
> read.

This concrete example is great, because it precisely illustrates a major 
objection I have to returning ~[T].

Reader.read_to_end() internally uses a 64k-byte vector. It reserves 64k bytes, 
then pushes onto this vector until it hits EOF. Every time it fills up the 64k 
capacity it reserves another chunk and keeps reading (this, btw, is I think 
almost certainly unintended behavior and is fixed by #13127, which changes it 
to always keep 64k of space available for each read rather than potentially 
requesting smaller and smaller reads). Note that because it uses 
reserve_at_least() it may actually have more than 64k available. When EOF is 
reached, this vector is returned to the caller.

The problem I have with returning ~[T] here is that both choices for how to 
deal with this wasted space are terrible:

1. Shrink-to-fit before returning. If I'm going to keep the vector around for a 
long time this is a good idea, but if I'm just going to process the vector and 
throw it away, the reallocation was completely unnecessary.
2. Convert to ~[T] without shrinking. The caller has no way to know about the 
potentially massive amount of wasted space. If I'm going to just process the 
vector and throw it away that's fine, but if I'm going to keep it around for a 
while then this is terrible.

The only reasonable solution is to return the Vec<T> and let the caller decide 
if they want to shrink-to-fit or not.

-Kevin Ballard
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to