@ 261027.5

231121.5 · 9c84575229131239f92149cd5790ddb553d7eea8

printer: drop dependency on serde_derive

As suggested by @epage[1].

Ad hoc timings on my i7-12900K:

before cargo build: 4.91s
before cargo build release: 8.05s
after cargo build: 4.69s
after cargo build release: 7.83s

... pretty underwhelming if you ask me. Ah well. And on my M2 mac mini:

before cargo build: 6.18s
before cargo build release: 14.50s
after cargo build: 5.52s
after cargo build release: 13.44s

Still kind of underwhelming, but definitely better. It shaves a full second off of compile times in release mode. I went back to my i7-12900K, but passed `-j1` to `cargo build` to force single threaded mode:

before cargo build: 19.44s
before cargo build release: 50.64s
after cargo build: 16.76s
after cargo build release: 48.00s

Which seems pretty consistent with the modest improvements above.

Looking at `cargo build --timings`, the beefiest chunk of time is spent in compiling `regex-automata`, by far. This is fine because it's core functionality. I wish a fast general purpose regex engine with its internals exposed as a separately versioned library didn't require so much code... Blech.

[1]: https://old.reddit.com/r/rust/comments/17rd8ww/faster_compilation_with_the_parallel_frontend_in/k8igjlg/

reading declarations

Changes to crates/printer/src/stats.rs. All files

crates/printer/src/stats.rs

@@ -10,7 +10,6 @@ use crate::util::NiceDuration; /// When statistics are reported by a printer, they correspond to all searches /// executed with that printer. #[derive(Clone, Debug, Default, PartialEq, Eq)]-#[cfg_attr(feature = "serde", derive(serde_derive::Serialize))] pub struct Stats {     elapsed: NiceDuration,     searches: u64,@@ -21,49 +20,6 @@ pub struct Stats {     matches: u64, } -impl Add for Stats {-    type Output = Stats;--    fn add(self, rhs: Stats) -> Stats {-        self + &rhs-    }-}--impl<'a> Add<&'a Stats> for Stats {-    type Output = Stats;--    fn add(self, rhs: &'a Stats) -> Stats {-        Stats {-            elapsed: NiceDuration(self.elapsed.0 + rhs.elapsed.0),-            searches: self.searches + rhs.searches,-            searches_with_match: self.searches_with_match-                + rhs.searches_with_match,-            bytes_searched: self.bytes_searched + rhs.bytes_searched,-            bytes_printed: self.bytes_printed + rhs.bytes_printed,-            matched_lines: self.matched_lines + rhs.matched_lines,-            matches: self.matches + rhs.matches,-        }-    }-}--impl AddAssign for Stats {-    fn add_assign(&mut self, rhs: Stats) {-        *self += &rhs;-    }-}--impl<'a> AddAssign<&'a Stats> for Stats {-    fn add_assign(&mut self, rhs: &'a Stats) {-        self.elapsed.0 += rhs.elapsed.0;-        self.searches += rhs.searches;-        self.searches_with_match += rhs.searches_with_match;-        self.bytes_searched += rhs.bytes_searched;-        self.bytes_printed += rhs.bytes_printed;-        self.matched_lines += rhs.matched_lines;-        self.matches += rhs.matches;-    }-}- impl Stats {     /// Return a new value for tracking aggregate statistics across searches.     ///@@ -147,3 +103,69 @@ impl Stats {         self.matches += n;     } }++impl Add for Stats {+    type Output = Stats;++    fn add(self, rhs: Stats) -> Stats {+        self + &rhs+    }+}++impl<'a> Add<&'a Stats> for Stats {+    type Output = Stats;++    fn add(self, rhs: &'a Stats) -> Stats {+        Stats {+            elapsed: NiceDuration(self.elapsed.0 + rhs.elapsed.0),+            searches: self.searches + rhs.searches,+            searches_with_match: self.searches_with_match+                + rhs.searches_with_match,+            bytes_searched: self.bytes_searched + rhs.bytes_searched,+            bytes_printed: self.bytes_printed + rhs.bytes_printed,+            matched_lines: self.matched_lines + rhs.matched_lines,+            matches: self.matches + rhs.matches,+        }+    }+}++impl AddAssign for Stats {+    fn add_assign(&mut self, rhs: Stats) {+        *self += &rhs;+    }+}++impl<'a> AddAssign<&'a Stats> for Stats {+    fn add_assign(&mut self, rhs: &'a Stats) {+        self.elapsed.0 += rhs.elapsed.0;+        self.searches += rhs.searches;+        self.searches_with_match += rhs.searches_with_match;+        self.bytes_searched += rhs.bytes_searched;+        self.bytes_printed += rhs.bytes_printed;+        self.matched_lines += rhs.matched_lines;+        self.matches += rhs.matches;+    }+}++#[cfg(feature = "serde")]+impl serde::Serialize for Stats {+    fn serialize<S: serde::Serializer>(+        &self,+        s: S,+    ) -> Result<S::Ok, S::Error> {+        use serde::ser::SerializeStruct;++        let mut state = s.serialize_struct("Stats", 7)?;+        state.serialize_field("elapsed", &self.elapsed)?;+        state.serialize_field("searches", &self.searches)?;+        state.serialize_field(+            "searches_with_match",+            &self.searches_with_match,+        )?;+        state.serialize_field("bytes_searched", &self.bytes_searched)?;+        state.serialize_field("bytes_printed", &self.bytes_printed)?;+        state.serialize_field("matched_lines", &self.matched_lines)?;+        state.serialize_field("matches", &self.matches)?;+        state.end()+    }+}