File tree 2 files changed +14
-5
lines changed
2 files changed +14
-5
lines changed Original file line number Diff line number Diff line change @@ -12,6 +12,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.
12
12
- Fix feature ` simd_support ` for recent nightly rust (#1586 )
13
13
- Add ` Alphabetic ` distribution. (#1587 )
14
14
- Re-export ` rand_core ` (#1602 )
15
+ - Boost performance of ` sample_floyd ` (#1621 )
15
16
16
17
## [ 0.9.0] - 2025-01-27
17
18
### Security and unsafe
Original file line number Diff line number Diff line change 8
8
9
9
//! Low-level API for sampling indices
10
10
use alloc:: vec:: { self , Vec } ;
11
+ use core:: ptr;
11
12
use core:: slice;
12
13
use core:: { hash:: Hash , ops:: AddAssign } ;
13
14
// BTreeMap is not as fast in tests, but better than nothing.
@@ -447,12 +448,19 @@ where
447
448
// the last entry. This bijection proves the algorithm fair.
448
449
debug_assert ! ( amount <= length) ;
449
450
let mut indices = Vec :: with_capacity ( amount as usize ) ;
450
- for j in length - amount..length {
451
- let t = rng. random_range ( ..=j) ;
452
- if let Some ( pos) = indices. iter ( ) . position ( |& x| x == t) {
453
- indices[ pos] = j;
451
+ let mut len = 0 ;
452
+ let ptr = indices. as_mut_ptr ( ) ;
453
+ // safety: the index is bounded by the length of indices
454
+ unsafe {
455
+ for j in length - amount..length {
456
+ let t = rng. random_range ( ..=j) ;
457
+ if let Some ( pos) = indices. iter ( ) . position ( |& x| x == t) {
458
+ * indices. get_unchecked_mut ( pos) = j;
459
+ }
460
+ ptr:: write ( ptr. add ( len) , t) ;
461
+ len += 1 ;
462
+ indices. set_len ( len) ;
454
463
}
455
- indices. push ( t) ;
456
464
}
457
465
IndexVec :: from ( indices)
458
466
}
You can’t perform that action at this time.
0 commit comments