The property of being more “efficient” can only apply to differences between the two versions. This rust-by-example page is quite confusing in my opinion, the way it’s presented; it should more clear about what kind of difference was made to the code and should refrain from unnecessarily re-formatting and re-ordering the code.
The actual differences being made is that
- the argument is generalized to any
AsRef<Path>
, which is a very minor efficiency benefit, and also a convenience benefit
- the return type becomes
Result
, resulting in better error handling ability
The comment at the end of the page seems completely nonsensical.
This process is more efficient than creating a String
in memory especially working with larger files.
This comment would make sense if the presented “Beginner friendly method” would use read_to_string
and a lines
iterator on the String
; but the way the code examples stand now, there’s barely any difference.
This problem seems to have been noticed already as the same page in the nightly
docs features a “naive” example that’s actually doing something significantly different – based on their comment, that’s also the version that @Michael-F-Bryan seems to be describing above.
Funnily enough, using the supposedly “inefficient” read_to_string
makes it a lot easier to avoid the overhead of creating lots of small owned String
s, because the lines
iterator on str
/String
creates borrowed &str
s by default anyways, and only by wrapping it into a helper function and adding something like .map(String::from)
, it re-gains the overhead of creating many small String
s.
Also, these new nightly docs still contain severe issues, as they claim
We also update read_lines
to return an iterator instead of allocating new String
objects in memory for each line.
which is just plain wrong (or at least awfully misleading), as far as I can tell. It implies that the iterator would not be creating new String
allocations for every line. While it’s true that creating a Vec
holding all the String
s is avoided, that overhead was arguably negligible compared to all the allocations of the Strings
themselves. While it’s true that the (shallow data of the) String
“objects” is no longer placed on the heap, most people will understand “allocating new String
objects” completely differently. Maybe it’s referring to the fact that the String
allocations don't necessarily exist at the same time anymore, but as it’s written that’s not what this sentence conveys to me either.
I’ve raised an issue for these concerns.