#780 (comment) by jswrenn
In the Rust standard library, it's quite common for fold to be implemented in terms of try_fold. In your original code you construct a TakeWhile and call fold on it. But TakeWhile's fold implementation delegates to try_fold!
The general rule to follow is something like this:
-
If you need to completely consume an iterator, use for_each or fold.
- Use
for_each if you don't need to maintain an accumulator.
- Use
fold if you do need to maintain an accumulator.
-
If you need to partly consume an iterator, use try_for_each or try_fold.
- Same rules about accumulators apply.
Bold is mine as I wonder if we are using for_each (convenient) at multiple places instead of fold.
Current for_each uses:
- lib.rs:
Itertools::{counts, partition_map, join}
- extrema_set.rs:
min_set_impl
- grouping_map.rs:
GroupingMap::{aggregate, collect}
- group_map.rs:
into_group_map
- k_smallest.rs:
k_smallest
(There is also Itertools::foreach but this one is okay.)
Why do I care? While benchmarking a new MapForGrouping::fold, I found out that some_slice_iter::for_each does not delegate to fold (default behavior) and is not optimized * (just while let Some(x) = self.next() { f(x); }) while some_slice_iter::fold is optimized (which is useful to see benchmark improvements of specializing fold methods of our adaptors by delegating to the inner iterator).
*: The for_each has a comment: "We override the default implementation, which uses try_fold, because this simple implementation generates less LLVM IR and is faster to compile."
#780 (comment) by jswrenn
Bold is mine as I wonder if we are using
for_each(convenient) at multiple places instead offold.Current
for_eachuses:Itertools::{counts, partition_map, join}min_set_implGroupingMap::{aggregate, collect}into_group_mapk_smallest(There is also
Itertools::foreachbut this one is okay.)Why do I care? While benchmarking a new
MapForGrouping::fold, I found out thatsome_slice_iter::for_eachdoes not delegate tofold(default behavior) and is not optimized * (justwhile let Some(x) = self.next() { f(x); }) whilesome_slice_iter::foldis optimized (which is useful to see benchmark improvements of specializingfoldmethods of our adaptors by delegating to the inner iterator).*: The
for_eachhas a comment: "We override the default implementation, which usestry_fold, because this simple implementation generates less LLVM IR and is faster to compile."