File tree Expand file tree Collapse file tree 2 files changed +17
-1
lines changed
Expand file tree Collapse file tree 2 files changed +17
-1
lines changed Original file line number Diff line number Diff line change @@ -19,6 +19,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.
1919- Remove fns ` SeedableRng::from_os_rng ` , ` try_from_os_rng ` (#1674 )
2020- Remove ` Clone ` support for ` StdRng ` , ` ReseedingRng ` (#1677 )
2121- Use ` postcard ` instead of ` bincode ` to test the serde feature (#1693 )
22+ - Avoid excessive allocation ` IteratorRandom::sample ` when ` amount ` is much larger than iterator size
2223
2324### Additions
2425- Add fns ` IndexedRandom::choose_iter ` , ` choose_weighted_iter ` (#1632 )
Original file line number Diff line number Diff line change @@ -245,7 +245,22 @@ pub trait IteratorRandom: Iterator + Sized {
245245 where
246246 R : Rng + ?Sized ,
247247 {
248- let mut reservoir = Vec :: with_capacity ( amount) ;
248+ let ( size_lower_bound, _size_upper_bound) = self . size_hint ( ) ;
249+
250+ // If the requested amount is much larger than the iterator size,
251+ // avoid excessive allocation even that it is temporary.
252+ // This also prevents allocation panic for small iterators but large requested amount.
253+ let capacity = core:: cmp:: min (
254+ amount,
255+ core:: cmp:: max (
256+ size_lower_bound,
257+ ( 32usize << 10 )
258+ . checked_div ( size_of :: < Self :: Item > ( ) )
259+ . unwrap_or ( 0 ) ,
260+ ) ,
261+ ) ;
262+
263+ let mut reservoir = Vec :: with_capacity ( capacity) ;
249264 reservoir. extend ( self . by_ref ( ) . take ( amount) ) ;
250265
251266 // Continue unless the iterator was exhausted
You can’t perform that action at this time.
0 commit comments