Skip to content

Commit 3616358

Browse files
committed
automata: add targeted inline(always) annotations
It turns out there are quite a few routines that don't seem to get inlined and we need to help the compiler make the right choice. This ends up having a pretty dramatic impact on benchmarks dominated by latency. The annotations are of course gated on the `perf-inline` feature. Fixes #1029
1 parent a47e245 commit 3616358

File tree

6 files changed

+17
-0
lines changed

6 files changed

+17
-0
lines changed

regex-automata/src/dfa/dense.rs

+7
Original file line numberDiff line numberDiff line change
@@ -3012,6 +3012,7 @@ impl<T: AsRef<[u32]>> DFA<T> {
30123012
/// Returns the index of the match state for the given ID. If the
30133013
/// given ID does not correspond to a match state, then this may
30143014
/// panic or produce an incorrect result.
3015+
#[cfg_attr(feature = "perf-inline", inline(always))]
30153016
fn match_state_index(&self, id: StateID) -> usize {
30163017
debug_assert!(self.is_match_state(id));
30173018
// This is one of the places where we rely on the fact that match
@@ -4599,6 +4600,7 @@ impl<T: AsRef<[u32]>> MatchStates<T> {
45994600
///
46004601
/// The match index is the index of the pattern ID for the given state.
46014602
/// The index must be less than `self.pattern_len(state_index)`.
4603+
#[cfg_attr(feature = "perf-inline", inline(always))]
46024604
fn pattern_id(&self, state_index: usize, match_index: usize) -> PatternID {
46034605
self.pattern_id_slice(state_index)[match_index]
46044606
}
@@ -4607,6 +4609,7 @@ impl<T: AsRef<[u32]>> MatchStates<T> {
46074609
///
46084610
/// The match state index is the state index minus the state index of the
46094611
/// first match state in the DFA.
4612+
#[cfg_attr(feature = "perf-inline", inline(always))]
46104613
fn pattern_len(&self, state_index: usize) -> usize {
46114614
self.slices()[state_index * 2 + 1].as_usize()
46124615
}
@@ -4615,24 +4618,28 @@ impl<T: AsRef<[u32]>> MatchStates<T> {
46154618
///
46164619
/// The match state index is the state index minus the state index of the
46174620
/// first match state in the DFA.
4621+
#[cfg_attr(feature = "perf-inline", inline(always))]
46184622
fn pattern_id_slice(&self, state_index: usize) -> &[PatternID] {
46194623
let start = self.slices()[state_index * 2].as_usize();
46204624
let len = self.pattern_len(state_index);
46214625
&self.pattern_ids()[start..start + len]
46224626
}
46234627

46244628
/// Returns the pattern ID offset slice of u32 as a slice of PatternID.
4629+
#[cfg_attr(feature = "perf-inline", inline(always))]
46254630
fn slices(&self) -> &[PatternID] {
46264631
wire::u32s_to_pattern_ids(self.slices.as_ref())
46274632
}
46284633

46294634
/// Returns the total number of match states.
4635+
#[cfg_attr(feature = "perf-inline", inline(always))]
46304636
fn len(&self) -> usize {
46314637
assert_eq!(0, self.slices().len() % 2);
46324638
self.slices().len() / 2
46334639
}
46344640

46354641
/// Returns the pattern ID slice of u32 as a slice of PatternID.
4642+
#[cfg_attr(feature = "perf-inline", inline(always))]
46364643
fn pattern_ids(&self) -> &[PatternID] {
46374644
wire::u32s_to_pattern_ids(self.pattern_ids.as_ref())
46384645
}

regex-automata/src/dfa/start.rs

+2
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,12 @@ impl StartKind {
6262
size_of::<u32>()
6363
}
6464

65+
#[cfg_attr(feature = "perf-inline", inline(always))]
6566
pub(crate) fn has_unanchored(&self) -> bool {
6667
matches!(*self, StartKind::Both | StartKind::Unanchored)
6768
}
6869

70+
#[cfg_attr(feature = "perf-inline", inline(always))]
6971
pub(crate) fn has_anchored(&self) -> bool {
7072
matches!(*self, StartKind::Both | StartKind::Anchored)
7173
}

regex-automata/src/util/alphabet.rs

+1
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,7 @@ impl ByteSet {
796796
}
797797

798798
/// Return true if and only if this set is empty.
799+
#[cfg_attr(feature = "perf-inline", inline(always))]
799800
pub(crate) fn is_empty(&self) -> bool {
800801
self.bits.0 == [0, 0]
801802
}

regex-automata/src/util/search.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1526,6 +1526,7 @@ impl Anchored {
15261526
/// assert!(Anchored::Yes.is_anchored());
15271527
/// assert!(Anchored::Pattern(PatternID::ZERO).is_anchored());
15281528
/// ```
1529+
#[inline]
15291530
pub fn is_anchored(&self) -> bool {
15301531
matches!(*self, Anchored::Yes | Anchored::Pattern(_))
15311532
}
@@ -1544,6 +1545,7 @@ impl Anchored {
15441545
/// let pid = PatternID::must(5);
15451546
/// assert_eq!(Some(pid), Anchored::Pattern(pid).pattern());
15461547
/// ```
1548+
#[inline]
15471549
pub fn pattern(&self) -> Option<PatternID> {
15481550
match *self {
15491551
Anchored::Pattern(pid) => Some(pid),

regex-automata/src/util/start.rs

+3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ impl StartByteMap {
7272
}
7373

7474
/// Return the forward starting configuration for the given `input`.
75+
#[cfg_attr(feature = "perf-inline", inline(always))]
7576
pub(crate) fn fwd(&self, input: &Input) -> Start {
7677
match input
7778
.start()
@@ -84,13 +85,15 @@ impl StartByteMap {
8485
}
8586

8687
/// Return the reverse starting configuration for the given `input`.
88+
#[cfg_attr(feature = "perf-inline", inline(always))]
8789
pub(crate) fn rev(&self, input: &Input) -> Start {
8890
match input.haystack().get(input.end()) {
8991
None => Start::Text,
9092
Some(&byte) => self.get(byte),
9193
}
9294
}
9395

96+
#[cfg_attr(feature = "perf-inline", inline(always))]
9497
fn get(&self, byte: u8) -> Start {
9598
self.map[usize::from(byte)]
9699
}

regex-automata/src/util/wire.rs

+2
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ impl core::fmt::Display for DeserializeError {
270270
}
271271

272272
/// Safely converts a `&[u32]` to `&[StateID]` with zero cost.
273+
#[cfg_attr(feature = "perf-inline", inline(always))]
273274
pub(crate) fn u32s_to_state_ids(slice: &[u32]) -> &[StateID] {
274275
// SAFETY: This is safe because StateID is defined to have the same memory
275276
// representation as a u32 (it is repr(transparent)). While not every u32
@@ -300,6 +301,7 @@ pub(crate) fn u32s_to_state_ids_mut(slice: &mut [u32]) -> &mut [StateID] {
300301
}
301302

302303
/// Safely converts a `&[u32]` to `&[PatternID]` with zero cost.
304+
#[cfg_attr(feature = "perf-inline", inline(always))]
303305
pub(crate) fn u32s_to_pattern_ids(slice: &[u32]) -> &[PatternID] {
304306
// SAFETY: This is safe because PatternID is defined to have the same
305307
// memory representation as a u32 (it is repr(transparent)). While not

0 commit comments

Comments
 (0)