aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2020-07-27 22:37:20 +0000
committerGitHub <noreply@github.com>2020-07-27 22:37:20 +0000
commit0310be12d3007e32be614c5df94653d29fcc1a8b (patch)
treefef8054b03206bb1ffc962705a93f25a29d59f7a
parentf53d1b7dcfb9a1101b297437fb135667dd908628 (diff)
downloadr-alacritty-vte-0310be12d3007e32be614c5df94653d29fcc1a8b.tar.gz
r-alacritty-vte-0310be12d3007e32be614c5df94653d29fcc1a8b.tar.bz2
r-alacritty-vte-0310be12d3007e32be614c5df94653d29fcc1a8b.zip
Improve parser performance
-rw-r--r--src/definitions.rs21
-rw-r--r--src/lib.rs53
2 files changed, 43 insertions, 31 deletions
diff --git a/src/definitions.rs b/src/definitions.rs
index 5d01623..fe7952d 100644
--- a/src/definitions.rs
+++ b/src/definitions.rs
@@ -48,27 +48,6 @@ pub enum Action {
BeginUtf8 = 15,
}
-impl State {
- #[inline]
- pub fn entry_action(self) -> Action {
- match self {
- State::CsiEntry | State::DcsEntry | State::Escape => Action::Clear,
- State::DcsPassthrough => Action::Hook,
- State::OscString => Action::OscStart,
- _ => Action::None,
- }
- }
-
- #[inline]
- pub fn exit_action(self) -> Action {
- match self {
- State::DcsPassthrough => Action::Unhook,
- State::OscString => Action::OscEnd,
- _ => Action::None,
- }
- }
-}
-
/// Unpack a u8 into a State and Action
///
/// The implementation of this assumes that there are *precisely* 16 variants for both Action and
diff --git a/src/lib.rs b/src/lib.rs
index 6234901..a99638a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -160,15 +160,32 @@ impl Parser {
self.perform_action(performer, action, byte);
},
state => {
- // Exit action for previous state
- let exit_action = self.state.exit_action();
- maybe_action!(exit_action, byte);
-
- // Transition action
- maybe_action!(action, byte);
-
- // Entry action for new state
- maybe_action!(state.entry_action(), byte);
+ match self.state {
+ State::DcsPassthrough => {
+ self.perform_action(performer, Action::Unhook, byte);
+ maybe_action!(action, byte);
+ },
+ State::OscString => {
+ self.perform_action(performer, Action::OscEnd, byte);
+ maybe_action!(action, byte);
+ },
+ _ => {
+ maybe_action!(action, byte);
+
+ match state {
+ State::CsiEntry | State::DcsEntry | State::Escape => {
+ self.perform_action(performer, Action::Clear, byte);
+ },
+ State::DcsPassthrough => {
+ self.perform_action(performer, Action::Hook, byte);
+ },
+ State::OscString => {
+ self.perform_action(performer, Action::OscStart, byte);
+ },
+ _ => (),
+ }
+ },
+ }
// Assume the new state
self.state = state;
@@ -294,7 +311,6 @@ impl Parser {
Action::EscDispatch => {
performer.esc_dispatch(self.intermediates(), self.ignoring, byte)
},
- Action::Ignore | Action::None => (),
Action::Collect => {
if self.intermediate_idx == MAX_INTERMEDIATES {
self.ignoring = true;
@@ -330,6 +346,8 @@ impl Parser {
self.param = 0;
},
Action::BeginUtf8 => self.process_utf8(performer, byte),
+ Action::Ignore => (),
+ Action::None => (),
}
}
}
@@ -903,4 +921,19 @@ mod bench {
}
});
}
+
+ #[bench]
+ fn state_changes(b: &mut Bencher) {
+ let input = b"\x1b]2;X\x1b\\ \x1b[0m \x1bP0@\x1b\\";
+ b.iter(|| {
+ let mut dispatcher = BenchDispatcher;
+ let mut parser = Parser::new();
+
+ for _ in 0..1_000 {
+ for byte in input {
+ parser.advance(&mut dispatcher, *byte);
+ }
+ }
+ });
+ }
}