Skip to content

Commit 096a5ea

Browse files
committed
regex: support perf-inline
This makes all uses of `#[inline(always)]` conditional on the `perf-inline` feature. This should reduce compile times and binary size, but may decrease match performance.
1 parent 1e7efa4 commit 096a5ea

File tree

5 files changed

+32
-31
lines changed

5 files changed

+32
-31
lines changed

src/dfa.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ impl CacheInner {
442442
}
443443

444444
impl<'a> Fsm<'a> {
445-
#[inline(always)] // reduces constant overhead
445+
#[cfg_attr(feature = "perf-inline", inline(always))]
446446
pub fn forward(
447447
prog: &'a Program,
448448
cache: &ProgramCache,
@@ -472,7 +472,7 @@ impl<'a> Fsm<'a> {
472472
dfa.exec_at(&mut cache.qcur, &mut cache.qnext, text)
473473
}
474474

475-
#[inline(always)] // reduces constant overhead
475+
#[cfg_attr(feature = "perf-inline", inline(always))]
476476
pub fn reverse(
477477
prog: &'a Program,
478478
cache: &ProgramCache,
@@ -502,7 +502,7 @@ impl<'a> Fsm<'a> {
502502
dfa.exec_at_reverse(&mut cache.qcur, &mut cache.qnext, text)
503503
}
504504

505-
#[inline(always)] // reduces constant overhead
505+
#[cfg_attr(feature = "perf-inline", inline(always))]
506506
pub fn forward_many(
507507
prog: &'a Program,
508508
cache: &ProgramCache,
@@ -550,7 +550,7 @@ impl<'a> Fsm<'a> {
550550
/// Executes the DFA on a forward NFA.
551551
///
552552
/// {qcur,qnext} are scratch ordered sets which may be non-empty.
553-
#[inline(always)] // reduces constant overhead
553+
#[cfg_attr(feature = "perf-inline", inline(always))]
554554
fn exec_at(
555555
&mut self,
556556
qcur: &mut SparseSet,
@@ -743,7 +743,7 @@ impl<'a> Fsm<'a> {
743743
}
744744

745745
/// Executes the DFA on a reverse NFA.
746-
#[inline(always)] // reduces constant overhead
746+
#[cfg_attr(feature = "perf-inline", inline(always))]
747747
fn exec_at_reverse(
748748
&mut self,
749749
qcur: &mut SparseSet,
@@ -848,7 +848,7 @@ impl<'a> Fsm<'a> {
848848
/// corresponds to text[i].
849849
///
850850
/// This elides bounds checks, and is therefore unsafe.
851-
#[inline(always)]
851+
#[cfg_attr(feature = "perf-inline", inline(always))]
852852
unsafe fn next_si(&self, si: StatePtr, text: &[u8], i: usize) -> StatePtr {
853853
// What is the argument for safety here?
854854
// We have three unchecked accesses that could possibly violate safety:
@@ -1363,7 +1363,7 @@ impl<'a> Fsm<'a> {
13631363
/// then it is computed, cached and a pointer to it is returned.
13641364
///
13651365
/// This may return STATE_DEAD but never STATE_UNKNOWN.
1366-
#[inline(always)] // reduces constant overhead
1366+
#[cfg_attr(feature = "perf-inline", inline(always))]
13671367
fn start_state(
13681368
&mut self,
13691369
q: &mut SparseSet,
@@ -1525,7 +1525,7 @@ impl<'a> Fsm<'a> {
15251525

15261526
/// Given an input byte or the special EOF sentinel, return its
15271527
/// corresponding byte class.
1528-
#[inline(always)]
1528+
#[cfg_attr(feature = "perf-inline", inline(always))]
15291529
fn byte_class(&self, b: Byte) -> usize {
15301530
match b.as_byte() {
15311531
None => self.num_byte_classes() - 1,
@@ -1534,7 +1534,7 @@ impl<'a> Fsm<'a> {
15341534
}
15351535

15361536
/// Like byte_class, but explicitly for u8s.
1537-
#[inline(always)]
1537+
#[cfg_attr(feature = "perf-inline", inline(always))]
15381538
fn u8_class(&self, b: u8) -> usize {
15391539
self.prog.byte_classes[b as usize] as usize
15401540
}

src/exec.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -362,22 +362,22 @@ impl<'c> RegularExpression for ExecNoSyncStr<'c> {
362362
next_utf8(text.as_bytes(), i)
363363
}
364364

365-
#[inline(always)] // reduces constant overhead
365+
#[cfg_attr(feature = "perf-inline", inline(always))]
366366
fn shortest_match_at(&self, text: &str, start: usize) -> Option<usize> {
367367
self.0.shortest_match_at(text.as_bytes(), start)
368368
}
369369

370-
#[inline(always)] // reduces constant overhead
370+
#[cfg_attr(feature = "perf-inline", inline(always))]
371371
fn is_match_at(&self, text: &str, start: usize) -> bool {
372372
self.0.is_match_at(text.as_bytes(), start)
373373
}
374374

375-
#[inline(always)] // reduces constant overhead
375+
#[cfg_attr(feature = "perf-inline", inline(always))]
376376
fn find_at(&self, text: &str, start: usize) -> Option<(usize, usize)> {
377377
self.0.find_at(text.as_bytes(), start)
378378
}
379379

380-
#[inline(always)] // reduces constant overhead
380+
#[cfg_attr(feature = "perf-inline", inline(always))]
381381
fn captures_read_at(
382382
&self,
383383
locs: &mut Locations,
@@ -404,7 +404,7 @@ impl<'c> RegularExpression for ExecNoSync<'c> {
404404

405405
/// Returns the end of a match location, possibly occurring before the
406406
/// end location of the correct leftmost-first match.
407-
#[inline(always)] // reduces constant overhead
407+
#[cfg_attr(feature = "perf-inline", inline(always))]
408408
fn shortest_match_at(&self, text: &[u8], start: usize) -> Option<usize> {
409409
if !self.is_anchor_end_match(text) {
410410
return None;
@@ -449,7 +449,7 @@ impl<'c> RegularExpression for ExecNoSync<'c> {
449449
///
450450
/// For single regular expressions, this is equivalent to calling
451451
/// shortest_match(...).is_some().
452-
#[inline(always)] // reduces constant overhead
452+
#[cfg_attr(feature = "perf-inline", inline(always))]
453453
fn is_match_at(&self, text: &[u8], start: usize) -> bool {
454454
if !self.is_anchor_end_match(text) {
455455
return false;
@@ -495,7 +495,7 @@ impl<'c> RegularExpression for ExecNoSync<'c> {
495495

496496
/// Finds the start and end location of the leftmost-first match, starting
497497
/// at the given location.
498-
#[inline(always)] // reduces constant overhead
498+
#[cfg_attr(feature = "perf-inline", inline(always))]
499499
fn find_at(&self, text: &[u8], start: usize) -> Option<(usize, usize)> {
500500
if !self.is_anchor_end_match(text) {
501501
return None;
@@ -639,7 +639,7 @@ impl<'c> RegularExpression for ExecNoSync<'c> {
639639

640640
impl<'c> ExecNoSync<'c> {
641641
/// Finds the leftmost-first match using only literal search.
642-
#[inline(always)] // reduces constant overhead
642+
#[cfg_attr(feature = "perf-inline", inline(always))]
643643
fn find_literals(
644644
&self,
645645
ty: MatchLiteralType,
@@ -682,7 +682,7 @@ impl<'c> ExecNoSync<'c> {
682682
///
683683
/// If the result returned indicates that the DFA quit, then another
684684
/// matching engine should be used.
685-
#[inline(always)] // reduces constant overhead
685+
#[cfg_attr(feature = "perf-inline", inline(always))]
686686
fn find_dfa_forward(
687687
&self,
688688
text: &[u8],
@@ -721,7 +721,7 @@ impl<'c> ExecNoSync<'c> {
721721
///
722722
/// If the result returned indicates that the DFA quit, then another
723723
/// matching engine should be used.
724-
#[inline(always)] // reduces constant overhead
724+
#[cfg_attr(feature = "perf-inline", inline(always))]
725725
fn find_dfa_anchored_reverse(
726726
&self,
727727
text: &[u8],
@@ -742,15 +742,15 @@ impl<'c> ExecNoSync<'c> {
742742
}
743743

744744
/// Finds the end of the shortest match using only the DFA.
745-
#[inline(always)] // reduces constant overhead
745+
#[cfg_attr(feature = "perf-inline", inline(always))]
746746
fn shortest_dfa(&self, text: &[u8], start: usize) -> dfa::Result<usize> {
747747
dfa::Fsm::forward(&self.ro.dfa, self.cache, true, text, start)
748748
}
749749

750750
/// Finds the end of the shortest match using only the DFA by scanning for
751751
/// suffix literals.
752752
///
753-
#[inline(always)] // reduces constant overhead
753+
#[cfg_attr(feature = "perf-inline", inline(always))]
754754
fn shortest_dfa_reverse_suffix(
755755
&self,
756756
text: &[u8],
@@ -775,7 +775,7 @@ impl<'c> ExecNoSync<'c> {
775775
///
776776
/// If the result returned indicates that the DFA quit, then another
777777
/// matching engine should be used.
778-
#[inline(always)] // reduces constant overhead
778+
#[cfg_attr(feature = "perf-inline", inline(always))]
779779
fn exec_dfa_reverse_suffix(
780780
&self,
781781
text: &[u8],
@@ -819,7 +819,7 @@ impl<'c> ExecNoSync<'c> {
819819
///
820820
/// If the result returned indicates that the DFA quit, then another
821821
/// matching engine should be used.
822-
#[inline(always)] // reduces constant overhead
822+
#[cfg_attr(feature = "perf-inline", inline(always))]
823823
fn find_dfa_reverse_suffix(
824824
&self,
825825
text: &[u8],
@@ -1118,7 +1118,7 @@ impl<'c> ExecNoSync<'c> {
11181118
}
11191119
}
11201120

1121-
#[inline(always)] // reduces constant overhead
1121+
#[cfg_attr(feature = "perf-inline", inline(always))]
11221122
fn is_anchor_end_match(&self, text: &[u8]) -> bool {
11231123
// Only do this check if the haystack is big (>1MB).
11241124
if text.len() > (1 << 20) && self.ro.nfa.is_anchored_end {
@@ -1143,7 +1143,7 @@ impl<'c> ExecNoSyncStr<'c> {
11431143

11441144
impl Exec {
11451145
/// Get a searcher that isn't Sync.
1146-
#[inline(always)] // reduces constant overhead
1146+
#[cfg_attr(feature = "perf-inline", inline(always))]
11471147
pub fn searcher(&self) -> ExecNoSync {
11481148
let create =
11491149
|| Box::new(RefCell::new(ProgramCacheInner::new(&self.ro)));
@@ -1154,7 +1154,7 @@ impl Exec {
11541154
}
11551155

11561156
/// Get a searcher that isn't Sync and can match on &str.
1157-
#[inline(always)] // reduces constant overhead
1157+
#[cfg_attr(feature = "perf-inline", inline(always))]
11581158
pub fn searcher_str(&self) -> ExecNoSyncStr {
11591159
ExecNoSyncStr(self.searcher())
11601160
}

src/literal.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl LiteralSearcher {
8080
}
8181

8282
/// Find the position of a literal in `haystack` if it exists.
83-
#[inline(always)] // reduces constant overhead
83+
#[cfg_attr(feature = "perf-inline", inline(always))]
8484
pub fn find(&self, haystack: &[u8]) -> Option<(usize, usize)> {
8585
use self::Matcher::*;
8686
match self.matcher {
@@ -339,7 +339,7 @@ impl SingleByteSet {
339339
}
340340

341341
/// Faster find that special cases certain sizes to use memchr.
342-
#[inline(always)] // reduces constant overhead
342+
#[cfg_attr(feature = "perf-inline", inline(always))]
343343
fn find(&self, text: &[u8]) -> Option<usize> {
344344
match self.dense.len() {
345345
0 => None,
@@ -452,7 +452,7 @@ impl FreqyPacked {
452452
}
453453
}
454454

455-
#[inline(always)] // reduces constant overhead
455+
#[cfg_attr(feature = "perf-inline", inline(always))]
456456
pub fn find(&self, haystack: &[u8]) -> Option<usize> {
457457
let pat = &*self.pat;
458458
if haystack.len() < pat.len() || pat.is_empty() {
@@ -478,7 +478,7 @@ impl FreqyPacked {
478478
None
479479
}
480480

481-
#[inline(always)] // reduces constant overhead
481+
#[cfg_attr(feature = "perf-inline", inline(always))]
482482
pub fn is_suffix(&self, text: &[u8]) -> bool {
483483
if text.len() < self.len() {
484484
return false;

src/prog.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ impl Program {
161161
impl Deref for Program {
162162
type Target = [Inst];
163163

164-
#[inline(always)]
164+
#[cfg_attr(feature = "perf-inline", inline(always))]
165165
fn deref(&self) -> &Self::Target {
166166
&*self.insts
167167
}

test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ cargo test
1010
features=(
1111
"std perf"
1212
"std perf unicode-perl"
13+
"std perf-cache perf-dfa perf-literal"
1314
)
1415
for f in "${features[@]}"; do
1516
echo "===== FEATURE: $f ==="

0 commit comments

Comments
 (0)