summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-12-21 21:29:59 +0000
committerGitHub <noreply@github.com>2021-12-21 21:29:59 +0000
commit4f7119c61da6ab3a11d5e52b5e6cf7105a66efb9 (patch)
treef0f4562bfd6f1296572078d08e46eab4e9185566 /src
parent1dcc582f8eba50f6233bc0bf398ada4032469c1f (diff)
parent644d36cf1fa5515dade300e42de6f9877c892204 (diff)
downloadnix-4f7119c61da6ab3a11d5e52b5e6cf7105a66efb9.zip
Merge #1583
1583: Remove unsafe in with_nix_path() for [u8] r=asomers a=rtzoeller Remove use of `unsafe` in the implementation of `with_nix_path()` for `[u8]`. This also comes with a nice determinism win across input sizes, and is fairly performance neutral (slightly slower for small strings, much faster for large strings). I suspect the performance degradation in the existing implementation is related to the following note in the `CStr::from_ptr()` documentation: > Note: This operation is intended to be a 0-cost cast but it is currently implemented with an up-front calculation of the length of the string. This is not guaranteed to always be the case. --- Tested with `cargo 1.57.0-nightly (7fbbf4e8f 2021-10-19)`, with variations of the following benchmarking code: ```rs #[bench] fn bench_with_nix_path_1024(b: &mut test::Bencher) { let bytes = std::hint::black_box([70u8; 1024]); b.iter(|| { bytes.with_nix_path(|cstr| { std::hint::black_box(&cstr); }).unwrap(); }) } ``` | Length | Before Change | After Change | |--------|-----------------------|-----------------------| | 16 | 37 ns/iter (+/- 0) | 44 ns/iter (+/- 0) | | 64 | 39 ns/iter (+/- 0) | 44 ns/iter (+/- 0) | | 256 | 84 ns/iter (+/- 0) | 48 ns/iter (+/- 0) | | 1024 | 232 ns/iter (+/- 1) | 50 ns/iter (+/- 1) | | 4095 | 796 ns/iter (+/- 8) | 62 ns/iter (+/- 2) | Co-authored-by: Ryan Zoeller <rtzoeller@rtzoeller.com>
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs18
1 files changed, 6 insertions, 12 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 96f56f6b..5d6a0cba 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -161,9 +161,9 @@ pub mod unistd;
*
*/
-use libc::{c_char, PATH_MAX};
+use libc::PATH_MAX;
-use std::{ptr, result};
+use std::result;
use std::ffi::{CStr, OsStr};
use std::os::unix::ffi::OsStrExt;
use std::path::{Path, PathBuf};
@@ -267,16 +267,10 @@ impl NixPath for [u8] {
return Err(Errno::ENAMETOOLONG)
}
- match self.iter().position(|b| *b == 0) {
- Some(_) => Err(Errno::EINVAL),
- None => {
- unsafe {
- // TODO: Replace with bytes::copy_memory. rust-lang/rust#24028
- ptr::copy_nonoverlapping(self.as_ptr(), buf.as_mut_ptr(), self.len());
- Ok(f(CStr::from_ptr(buf.as_ptr() as *const c_char)))
- }
-
- }
+ buf[..self.len()].copy_from_slice(self);
+ match CStr::from_bytes_with_nul(&buf[..=self.len()]) {
+ Ok(s) => Ok(f(s)),
+ Err(_) => Err(Errno::EINVAL),
}
}
}