Skip to content

Commit bb54af5

Browse files
committed
30X performance improvement in with_nix_path by not initializing memory
Signed-off-by: Alex Saveau <[email protected]>
1 parent 2143ffe commit bb54af5

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
syntax: glob
22
Cargo.lock
33
target
4+
.idea
45
*.diff
56
*.rej
67
*.orig

src/lib.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,9 @@ pub mod unistd;
163163

164164
use libc::PATH_MAX;
165165

166-
use std::result;
166+
use std::{ptr, result, slice};
167167
use std::ffi::{CStr, OsStr};
168+
use std::mem::MaybeUninit;
168169
use std::os::unix::ffi::OsStrExt;
169170
use std::path::{Path, PathBuf};
170171

@@ -260,15 +261,22 @@ impl NixPath for [u8] {
260261
}
261262

262263
fn with_nix_path<T, F>(&self, f: F) -> Result<T>
263-
where F: FnOnce(&CStr) -> T {
264-
let mut buf = [0u8; PATH_MAX as usize];
265-
264+
where
265+
F: FnOnce(&CStr) -> T,
266+
{
266267
if self.len() >= PATH_MAX as usize {
267-
return Err(Errno::ENAMETOOLONG)
268+
return Err(Errno::ENAMETOOLONG);
269+
}
270+
271+
let mut buf = MaybeUninit::<[u8; PATH_MAX as usize]>::uninit();
272+
let buf_ptr = buf.as_mut_ptr() as *mut u8;
273+
274+
unsafe {
275+
ptr::copy_nonoverlapping(self.as_ptr(), buf_ptr, self.len());
276+
buf_ptr.add(self.len()).write(0);
268277
}
269278

270-
buf[..self.len()].copy_from_slice(self);
271-
match CStr::from_bytes_with_nul(&buf[..=self.len()]) {
279+
match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, self.len() + 1) }) {
272280
Ok(s) => Ok(f(s)),
273281
Err(_) => Err(Errno::EINVAL),
274282
}

0 commit comments

Comments
 (0)