From 52d58efa23e33d57fc9983bbd15508e9c669906b Mon Sep 17 00:00:00 2001 From: Lol3rrr Date: Thu, 17 Oct 2024 17:43:11 +0200 Subject: [PATCH] Add basic benchmarks and CI --- .github/workflows/benchmark.yaml | 22 +++++++++ .github/workflows/test.yaml | 42 ++++++++++++++++ Cargo.lock | 82 +++++++++++++++++++++++++++++++- Cargo.toml | 5 ++ benches/example.rs | 34 +++++++++++++ src/game_event.rs | 4 +- src/parser/propcontroller.rs | 11 +++-- src/structured.rs | 23 ++++++--- 8 files changed, 209 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/benchmark.yaml create mode 100644 .github/workflows/test.yaml create mode 100644 benches/example.rs diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml new file mode 100644 index 0000000..cb01549 --- /dev/null +++ b/.github/workflows/benchmark.yaml @@ -0,0 +1,22 @@ +name: Benchmark + +on: + push: + +jobs: + benchmark: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + lfs: 'true' + submodules: 'recursive' + - name: Install latest nightly + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + - name: Install Protoc + uses: arduino/setup-protoc@v3 + - name: Run Tests + run: cargo bench diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..5716843 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,42 @@ +name: Testing/Linting + +on: + push: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + lfs: 'true' + submodules: 'recursive' + - name: Install latest nightly + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + - name: Install Protoc + uses: arduino/setup-protoc@v3 + - name: Run Tests + run: cargo test + + lint: + runs-on: ubuntu-latest + strategy: + matrix: + crate: [analysis, backend] + steps: + - uses: actions/checkout@v4 + - name: Install latest nightly + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + components: rustfmt, clippy + - name: Install Protoc + uses: arduino/setup-protoc@v3 + - name: Run Clippy + run: cargo clippy + - name: Run formatting + run: cargo fmt --check diff --git a/Cargo.lock b/Cargo.lock index 6741c65..3af64fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -11,6 +11,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + [[package]] name = "anyhow" version = "1.0.88" @@ -41,11 +47,44 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstyle", + "clap_lex", + "terminal_size", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "condtype" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf0a07a401f374238ab8e2f11a104d2851bf9ce711ec69804834de8af45c7af" + [[package]] name = "csdemo" version = "0.1.0" dependencies = [ "bitter", + "divan", "phf", "pretty_assertions", "prost", @@ -61,6 +100,31 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" +[[package]] +name = "divan" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d567df2c9c2870a43f3f2bd65aaeb18dbce1c18f217c3e564b4fbaeb3ee56c" +dependencies = [ + "cfg-if", + "clap", + "condtype", + "divan-macros", + "libc", + "regex-lite", +] + +[[package]] +name = "divan-macros" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27540baf49be0d484d8f0130d7d8da3011c32a44d4fc873368154f1510e574a2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "either" version = "1.13.0" @@ -343,6 +407,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "regex-syntax" version = "0.8.4" @@ -398,6 +468,16 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "terminal_size" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" +dependencies = [ + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "unicode-ident" version = "1.0.13" diff --git a/Cargo.toml b/Cargo.toml index b874784..10a8e72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,11 @@ regex = "1.10.6" [dev-dependencies] pretty_assertions = { version = "1.4" } +divan = "0.1.14" + +[[bench]] +name = "example" +harness = false [build-dependencies] prost-build = { version = "0.13.2" } diff --git a/benches/example.rs b/benches/example.rs new file mode 100644 index 0000000..18129cf --- /dev/null +++ b/benches/example.rs @@ -0,0 +1,34 @@ +#[global_allocator] +static ALLOC: divan::AllocProfiler = divan::AllocProfiler::system(); + +fn main() { + divan::main(); +} + +mod eager { + #[divan::bench(max_time = std::time::Duration::from_secs(30))] + fn no_entities_mirage() -> csdemo::parser::FirstPassOutput { + let raw_bytes = include_bytes!("../testfiles/mirage.dem"); + + let container = csdemo::Container::parse(divan::black_box(raw_bytes.as_slice())).unwrap(); + + csdemo::parser::parse( + csdemo::FrameIterator::parse(container.inner), + csdemo::parser::EntityFilter::disabled(), + ) + .unwrap() + } + + #[divan::bench(max_time = std::time::Duration::from_secs(30))] + fn entities_mirage() -> csdemo::parser::FirstPassOutput { + let raw_bytes = include_bytes!("../testfiles/mirage.dem"); + + let container = csdemo::Container::parse(divan::black_box(raw_bytes.as_slice())).unwrap(); + + csdemo::parser::parse( + csdemo::FrameIterator::parse(container.inner), + csdemo::parser::EntityFilter::all(), + ) + .unwrap() + } +} diff --git a/src/game_event.rs b/src/game_event.rs index 923955e..884fde4 100644 --- a/src/game_event.rs +++ b/src/game_event.rs @@ -12,9 +12,9 @@ macro_rules! define_event { impl $name { #[allow(unused_mut)] fn parse(keys: &[crate::csgo_proto::csvc_msg_game_event_list::KeyT], event: crate::csgo_proto::CMsgSource1LegacyGameEvent) -> Result { - + $(let mut $field: Option = None;)* - let mut remaining = std::collections::HashMap::new(); + let mut remaining = std::collections::HashMap::new(); for (k, f) in keys.iter().zip(event.keys.into_iter()) { let name = k.name(); diff --git a/src/parser/propcontroller.rs b/src/parser/propcontroller.rs index 7dde1fc..cb26c2b 100644 --- a/src/parser/propcontroller.rs +++ b/src/parser/propcontroller.rs @@ -135,10 +135,13 @@ impl PropController { prop_name: "my_weapons_offset".into(), }, ), - (ITEM_PURCHASE_COST, PropInfo { - id: ITEM_PURCHASE_COST, - prop_name: "item_purchase_cost".into(), - }), + ( + ITEM_PURCHASE_COST, + PropInfo { + id: ITEM_PURCHASE_COST, + prop_name: "item_purchase_cost".into(), + }, + ), ] .into_iter() .collect(), diff --git a/src/structured.rs b/src/structured.rs index d90a133..88c2ed3 100644 --- a/src/structured.rs +++ b/src/structured.rs @@ -37,16 +37,19 @@ pub mod ccsteam { } pub fn team_name(&self) -> Option<&str> { - self.0.get_prop("CCSTeam.m_szTeamname").map(|p| { - match &p.value { + self.0 + .get_prop("CCSTeam.m_szTeamname") + .map(|p| match &p.value { crate::parser::Variant::String(v) => Some(v.as_str()), _ => None, - } - }).flatten() + }) + .flatten() } pub fn player_pawns(&self) -> Vec { - self.0.props.iter() + self.0 + .props + .iter() .filter(|p| p.prop_info.prop_name.as_ref() == "CCSTeam.m_aPawns") .filter_map(|p| p.value.as_u32()) .map(|v| super::pawnid::PawnID::from(v)) @@ -54,11 +57,17 @@ pub mod ccsteam { } pub fn score(&self) -> Option { - self.0.get_prop("CCSTeam.m_iScore").map(|p| p.value.as_i32()).flatten() + self.0 + .get_prop("CCSTeam.m_iScore") + .map(|p| p.value.as_i32()) + .flatten() } pub fn team_number(&self) -> Option { - self.0.get_prop("CCSTeam.m_iTeamNum").map(|p| p.value.as_u32()).flatten() + self.0 + .get_prop("CCSTeam.m_iTeamNum") + .map(|p| p.value.as_u32()) + .flatten() } } }