From bb54af538d607530f3a67679ad8c0ca8cd5759b3 Mon Sep 17 00:00:00 2001 From: Alex Saveau Date: Wed, 2 Feb 2022 19:40:50 -0800 Subject: 30X performance improvement in with_nix_path by not initializing memory Signed-off-by: Alex Saveau --- src/lib.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 5d6a0cba..6d7ff55b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -163,8 +163,9 @@ pub mod unistd; use libc::PATH_MAX; -use std::result; +use std::{ptr, result, slice}; use std::ffi::{CStr, OsStr}; +use std::mem::MaybeUninit; use std::os::unix::ffi::OsStrExt; use std::path::{Path, PathBuf}; @@ -260,15 +261,22 @@ impl NixPath for [u8] { } fn with_nix_path(&self, f: F) -> Result - where F: FnOnce(&CStr) -> T { - let mut buf = [0u8; PATH_MAX as usize]; - + where + F: FnOnce(&CStr) -> T, + { if self.len() >= PATH_MAX as usize { - return Err(Errno::ENAMETOOLONG) + return Err(Errno::ENAMETOOLONG); + } + + let mut buf = MaybeUninit::<[u8; PATH_MAX as usize]>::uninit(); + let buf_ptr = buf.as_mut_ptr() as *mut u8; + + unsafe { + ptr::copy_nonoverlapping(self.as_ptr(), buf_ptr, self.len()); + buf_ptr.add(self.len()).write(0); } - buf[..self.len()].copy_from_slice(self); - match CStr::from_bytes_with_nul(&buf[..=self.len()]) { + match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, self.len() + 1) }) { Ok(s) => Ok(f(s)), Err(_) => Err(Errno::EINVAL), } -- cgit v1.2.3