-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use memchr to speed up [u8]::contains 3x #46713
Conversation
related: #46704 #![feature(test)]
extern crate test;
use test::Bencher;
#[bench]
fn find_byte(b: &mut Bencher) {
let x = test::black_box("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.").as_bytes();
b.iter(|| test::black_box(x.contains(&0xff)));
}
#[bench]
fn find_byte_old(b: &mut Bencher) {
let x = test::black_box("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.").as_bytes();
b.iter(|| test::black_box(x.iter().any(|x| *x == 0xff)));
}
Apparently our memchr implementation is actually slower than glibc, but @mystor is looking into that. I also get similar numbers if I implement |
I'll next be working to speed up #46693 |
r? @bluss |
src/libcore/slice/memchr.rs
Outdated
x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0 | ||
} | ||
|
||
#[cfg(target_pointer_width = "32")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this going to work on 16-bit platforms as well? I'm asking because I already broke rustc once by neglecting those. :) #40832
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. It looks like it should work. But idk.
This PR is contained in #46735 (but feel free to land separately, this is a simpler change) |
How implausible it would be to start depending on memchr crate rather than including it verbatim, now that we have ability to depend on crates? |
If I'm up to date, there are no third party crates pulled in by libstd. All the crates.io dependencies are in compiler crates and tools. Not sure if there's any reason for what or if it just never came up before. |
libcore can't depend on other crates; libcore contains most of the
machinery that lets you write a crate.
Also it can't link to libc, which memchr does. We can use this to only
depend on the Rust impl, but the Rust impl requires libcore to exist.
…-Manish Goregaokar
On Fri, Dec 15, 2017 at 6:19 AM, Robin Kruppe ***@***.***> wrote:
If I'm up to date, there are no third party crates pulled in by libstd.
All the crates.io dependencies are in compiler crates and tools. Not sure
if there's any reason for what or if it just never came up before.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#46713 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABivSIXhWuMRUPak2fVx-Zkd-vWswtJ7ks5tAmPugaJpZM4RAxfl>
.
|
@@ -12,4 +12,4 @@ | |||
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch | |||
|
|||
// Fallback memchr is fastest on windows |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Side note, this statement (Fallback memchr is fastest on windows) can be revisited by someone with the right development environment.
fn slice_contains(&self, x: &[Self]) -> bool { | ||
memchr::memchr(*self, x).is_some() | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could add for i8
here too. Reinterpreting &[i8]
as &[u8]
is problem free
I'm glad to hear that the loopiness of Rust's bootstrapping does have a limit :-) This PR looks good to me. The drawback is to add an unstable API (memchr function) to core with no intention of stabilizing it, that's normally not so popular. |
We already have a bunch of these APIs, like Can I land this, r=you? This PR was split out so that it's easy to land independently if we want to. |
Oh, hold on, adding an i8 impl |
Done. r? |
Use memchr for str::find(char) This is a 10x improvement for searching for characters. This also contains the patches from #46713 . Feel free to land both separately or together. cc @mystor @alexcrichton r? @bluss fixes #46693
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for being so slow :/ The review comments are about that transmute
is a very convenient interface, but we prefer everything but transmute.
src/libcore/slice/mod.rs
Outdated
|
||
impl SliceContains for i8 { | ||
fn slice_contains(&self, x: &[Self]) -> bool { | ||
let byte: u8 = unsafe { mem::transmute::<i8, u8>(*self) }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be a cast with as
.
src/libcore/slice/mod.rs
Outdated
impl SliceContains for i8 { | ||
fn slice_contains(&self, x: &[Self]) -> bool { | ||
let byte: u8 = unsafe { mem::transmute::<i8, u8>(*self) }; | ||
let bytes: &[u8] = unsafe { mem::transmute::<&[i8], &[u8]>(x) }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This with slice::from_raw_parts
cast with |
|
That's also UB iirc.
…On Dec 31, 2017 8:08 PM, "Robin Kruppe" ***@***.***> wrote:
as casts don't do overflow checks so they simply reinterpret the bits
when casting between uN and iN.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#46713 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABivSIZAbObu6l9-PdSgVSzKutZiHGzPks5tF5xKgaJpZM4RAxfl>
.
|
UB?!? No. |
We've had problems with casts being UB which iirc aren't fixed yet. Idk if
that's true for this specific cast.
…On Dec 31, 2017 8:20 PM, "Robin Kruppe" ***@***.***> wrote:
UB?!? No.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#46713 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABivSJvaVlsuSnGl0lbdgVlJoAU2NZNbks5tF58vgaJpZM4RAxfl>
.
|
In Rust the u8 to i8 cast using |
Cool. Will fix then.
…On Dec 31, 2017 8:23 PM, "bluss" ***@***.***> wrote:
In Rust the u8 to i8 cast using as is equivalent to the transmute in the
sense that the input and output are bitwise equivalent.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#46713 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABivSHMr4LJw4Gtt6S-u3uvHhjxmnfDoks5tF5_ugaJpZM4RAxfl>
.
|
|
Updated |
@bors r+ |
📌 Commit 4ef6847 has been approved by |
Use memchr to speed up [u8]::contains 3x None
☀️ Test successful - status-appveyor, status-travis |
Use memchr for str::find(char) This is a 10x improvement for searching for characters. This also contains the patches from #46713 . Feel free to land both separately or together. cc @mystor @alexcrichton r? @bluss fixes #46693
Is this, which was mentioned above: "Casting to a less wide integer will truncate the LSB bits." really true? Isn't it the MSB which are truncated? 257u32 as u8 is 1u8, right? |
Ah, indeed. Overworked me switches the terms. Happens all the time. Edited the comment to reflect the reality for future prosperity. |
No description provided.