diff options
author | Christian Duerr <contact@christianduerr.com> | 2020-07-27 22:37:20 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-27 22:37:20 +0000 |
commit | 0310be12d3007e32be614c5df94653d29fcc1a8b (patch) | |
tree | fef8054b03206bb1ffc962705a93f25a29d59f7a | |
parent | f53d1b7dcfb9a1101b297437fb135667dd908628 (diff) | |
download | r-alacritty-vte-0310be12d3007e32be614c5df94653d29fcc1a8b.tar.gz r-alacritty-vte-0310be12d3007e32be614c5df94653d29fcc1a8b.tar.bz2 r-alacritty-vte-0310be12d3007e32be614c5df94653d29fcc1a8b.zip |
Improve parser performance
-rw-r--r-- | src/definitions.rs | 21 | ||||
-rw-r--r-- | src/lib.rs | 53 |
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 @@ -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); + } + } + }); + } } |