Skip to content

Conversation

@rtzoeller
Copy link
Collaborator

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:

#[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)

@asomers asomers added this to the 0.24.0 milestone Nov 17, 2021
Copy link
Member

@asomers asomers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@asomers
Copy link
Member

asomers commented Dec 21, 2021

bors r+

@bors bors bot merged commit 4f7119c into nix-rust:master Dec 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants