Skip to content

Commit

Permalink
perf: add a faster skip_until using SIMD memchr (#745)
Browse files Browse the repository at this point in the history
it was put under the "memchr" feature-flag, as memchr SIMD support
is only on x86_64 at the moment (json bench is ~8% faster over baseline there):
#737 (comment)
once memchr has the Arm SIMD support, this could be perhaps the default
implementation.
For Aho-Corasick, it'll require more investigation.

Co-authored-by: Tomas Tauber <me@tomtau.be>
  • Loading branch information
tomtau and Tomas Tauber committed Dec 2, 2022
1 parent ca11433 commit 1e40766
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 19 deletions.
8 changes: 4 additions & 4 deletions debugger/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "pest_debugger"
description = "pest grammar debugger"
version = "2.5.0"
version = "2.5.1"
edition = "2021"
authors = ["Dragoș Tiselice <dragostiselice@gmail.com>", "Tomas Tauber <me@tomtau.be>"]
homepage = "https://pest.rs/"
Expand All @@ -14,9 +14,9 @@ readme = "_README.md"
rust-version = "1.56"

[dependencies]
pest = { path = "../pest", version = "2.5.0" }
pest_meta = { path = "../meta", version = "2.5.0" }
pest_vm = { path = "../vm", version = "2.5.0" }
pest = { path = "../pest", version = "2.5.1" }
pest_meta = { path = "../meta", version = "2.5.1" }
pest_vm = { path = "../vm", version = "2.5.1" }
rustyline = "10"
thiserror = "1"

Expand Down
6 changes: 3 additions & 3 deletions derive/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "pest_derive"
description = "pest's derive macro"
version = "2.5.0"
version = "2.5.1"
edition = "2021"
authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
homepage = "https://pest.rs/"
Expand All @@ -23,5 +23,5 @@ std = ["pest/std", "pest_generator/std"]

[dependencies]
# for tests, included transitively anyway
pest = { path = "../pest", version = "2.5.0", default-features = false }
pest_generator = { path = "../generator", version = "2.5.0", default-features = false }
pest = { path = "../pest", version = "2.5.1", default-features = false }
pest_generator = { path = "../generator", version = "2.5.1", default-features = false }
6 changes: 3 additions & 3 deletions generator/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "pest_generator"
description = "pest code generator"
version = "2.5.0"
version = "2.5.1"
edition = "2021"
authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
homepage = "https://pest.rs/"
Expand All @@ -18,8 +18,8 @@ default = ["std"]
std = ["pest/std"]

[dependencies]
pest = { path = "../pest", version = "2.5.0", default-features = false }
pest_meta = { path = "../meta", version = "2.5.0" }
pest = { path = "../pest", version = "2.5.1", default-features = false }
pest_meta = { path = "../meta", version = "2.5.1" }
proc-macro2 = "1.0"
quote = "1.0"
syn = "1.0"
6 changes: 3 additions & 3 deletions grammars/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "pest_grammars"
description = "pest popular grammar implementations"
version = "2.5.0"
version = "2.5.1"
edition = "2021"
authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
homepage = "https://pest.rs/"
Expand All @@ -14,8 +14,8 @@ readme = "_README.md"
rust-version = "1.56"

[dependencies]
pest = { path = "../pest", version = "2.5.0" }
pest_derive = { path = "../derive", version = "2.5.0" }
pest = { path = "../pest", version = "2.5.1" }
pest_derive = { path = "../derive", version = "2.5.1" }

[dev-dependencies]
criterion = "0.3"
Expand Down
4 changes: 2 additions & 2 deletions meta/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "pest_meta"
description = "pest meta language parser and validator"
version = "2.5.0"
version = "2.5.1"
edition = "2021"
authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
homepage = "https://pest.rs/"
Expand All @@ -16,7 +16,7 @@ include = ["Cargo.toml", "src/**/*", "src/grammar.rs", "_README.md", "LICENSE-*"
rust-version = "1.56"

[dependencies]
pest = { path = "../pest", version = "2.5.0" }
pest = { path = "../pest", version = "2.5.1" }
once_cell = "1.8.0"

[build-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion pest/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "pest"
description = "The Elegant Parser"
version = "2.5.0"
version = "2.5.1"
edition = "2021"
authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
homepage = "https://pest.rs/"
Expand Down
54 changes: 54 additions & 0 deletions pest/src/position.rs
Expand Up @@ -266,6 +266,60 @@ impl<'i> Position<'i> {
/// this function will return `false` but its `pos` will *still* be updated.
#[inline]
pub(crate) fn skip_until(&mut self, strings: &[&str]) -> bool {
#[cfg(not(feature = "memchr"))]
{
self.skip_until_basic(strings)
}
#[cfg(feature = "memchr")]
{
match strings {
[] => (),
[s1] => {
if let Some(from) =
memchr::memmem::find(&self.input.as_bytes()[self.pos..], s1.as_bytes())
{
self.pos += from;
return true;
}
}
[s1, s2] if !s1.is_empty() && !s2.is_empty() => {
let b1 = s1.as_bytes()[0];
let b2 = s2.as_bytes()[0];
let miter = memchr::memchr2_iter(b1, b2, &self.input.as_bytes()[self.pos..]);
for from in miter {
let start = &self.input[self.pos + from..];
if start.starts_with(s1) || start.starts_with(s2) {
self.pos += from;
return true;
}
}
}
[s1, s2, s3] if !s1.is_empty() && !s2.is_empty() && s3.is_empty() => {
let b1 = s1.as_bytes()[0];
let b2 = s2.as_bytes()[0];
let b3 = s2.as_bytes()[0];
let miter =
memchr::memchr3_iter(b1, b2, b3, &self.input.as_bytes()[self.pos..]);
for from in miter {
let start = &self.input[self.pos + from..];
if start.starts_with(s1) || start.starts_with(s2) || start.starts_with(s3) {
self.pos += from;
return true;
}
}
}
_ => {
return self.skip_until_basic(strings);
}
}
self.pos = self.input.len();
false
}
}

#[inline]
fn skip_until_basic(&mut self, strings: &[&str]) -> bool {
// TODO: optimize with Aho-Corasick, e.g. https://crates.io/crates/daachorse?
for from in self.pos..self.input.len() {
let bytes = if let Some(string) = self.input.get(from..) {
string.as_bytes()
Expand Down
6 changes: 3 additions & 3 deletions vm/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "pest_vm"
description = "pest grammar virtual machine"
version = "2.5.0"
version = "2.5.1"
edition = "2021"
authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
homepage = "https://pest.rs/"
Expand All @@ -14,5 +14,5 @@ readme = "_README.md"
rust-version = "1.56"

[dependencies]
pest = { path = "../pest", version = "2.5.0" }
pest_meta = { path = "../meta", version = "2.5.0" }
pest = { path = "../pest", version = "2.5.1" }
pest_meta = { path = "../meta", version = "2.5.1" }

0 comments on commit 1e40766

Please sign in to comment.