@@ -3,6 +3,7 @@ extern crate test;
3
3
4
4
use std:: {
5
5
alloc:: { alloc_zeroed, dealloc, Layout } ,
6
+ mem:: { self , MaybeUninit } ,
6
7
ptr:: NonNull ,
7
8
} ;
8
9
@@ -59,6 +60,20 @@ fn bench_with_init<const N: usize>(b: &mut test::Bencher) {
59
60
b. bytes = N as u64 ;
60
61
}
61
62
63
+ // Used to benchmark the benefit of `getrandom_uninit` compared to
64
+ // zero-initializing a buffer and then using `getrandom` (`bench_with_init`
65
+ // above).
66
+ #[ inline( always) ]
67
+ fn bench_uninit < const N : usize > ( b : & mut test:: Bencher ) {
68
+ let mut ab = AlignedBuffer :: < N > :: new ( ) ;
69
+ let buf = ab. buf ( ) ;
70
+ // SAFETY: `buf` doesn't escape this scope.
71
+ let buf = unsafe { slice_as_uninit_mut ( buf) } ;
72
+ b. iter ( || {
73
+ let _ = getrandom:: getrandom_uninit_slice ( buf) ;
74
+ } )
75
+ }
76
+
62
77
// 32 bytes (256-bit) is the seed sized used for rand::thread_rng
63
78
const SEED : usize = 32 ;
64
79
// Common size of a page, 4 KiB
@@ -74,6 +89,10 @@ fn bench_seed(b: &mut test::Bencher) {
74
89
fn bench_seed_init ( b : & mut test:: Bencher ) {
75
90
bench_with_init :: < SEED > ( b) ;
76
91
}
92
+ #[ bench]
93
+ fn bench_seed_uninit ( b : & mut test:: Bencher ) {
94
+ bench_uninit :: < SEED > ( b) ;
95
+ }
77
96
78
97
#[ bench]
79
98
fn bench_page ( b : & mut test:: Bencher ) {
@@ -83,6 +102,10 @@ fn bench_page(b: &mut test::Bencher) {
83
102
fn bench_page_init ( b : & mut test:: Bencher ) {
84
103
bench_with_init :: < PAGE > ( b) ;
85
104
}
105
+ #[ bench]
106
+ fn bench_page_uninit ( b : & mut test:: Bencher ) {
107
+ bench_uninit :: < PAGE > ( b) ;
108
+ }
86
109
87
110
#[ bench]
88
111
fn bench_large ( b : & mut test:: Bencher ) {
@@ -92,3 +115,14 @@ fn bench_large(b: &mut test::Bencher) {
92
115
fn bench_large_init ( b : & mut test:: Bencher ) {
93
116
bench_with_init :: < LARGE > ( b) ;
94
117
}
118
+ #[ bench]
119
+ fn bench_large_uninit ( b : & mut test:: Bencher ) {
120
+ bench_uninit :: < LARGE > ( b) ;
121
+ }
122
+
123
+ // TODO: Safety note.
124
+ #[ inline( always) ]
125
+ unsafe fn slice_as_uninit_mut < T > ( slice : & mut [ T ] ) -> & mut [ MaybeUninit < T > ] {
126
+ // SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.
127
+ mem:: transmute ( slice)
128
+ }
0 commit comments