forked from Leafwing-Studios/leafwing-input-manager
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add basic benchmarks (Leafwing-Studios#332)
* Scaffolding * Added simple benchmarks * Use latest version of criterion * Add benchmark for ActionState::update * Add benchmarks for which_pressed * Move app creation outside of the benchmark loop * Move initialization out of the benchmarks * Benchmark actionstate creation
- Loading branch information
1 parent
120a3d2
commit 97ab7ed
Showing
4 changed files
with
179 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use criterion::{criterion_group, criterion_main, Criterion}; | ||
use leafwing_input_manager::{ | ||
action_state::{ActionData, Timing}, | ||
buttonlike::ButtonState, | ||
prelude::ActionState, | ||
Actionlike, | ||
}; | ||
|
||
#[derive(Actionlike, Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
enum TestAction { | ||
A, | ||
B, | ||
C, | ||
D, | ||
E, | ||
F, | ||
G, | ||
H, | ||
I, | ||
J, | ||
} | ||
|
||
fn pressed(action_state: &ActionState<TestAction>) -> bool { | ||
action_state.pressed(TestAction::A) | ||
} | ||
|
||
fn just_pressed(action_state: &ActionState<TestAction>) -> bool { | ||
action_state.just_pressed(TestAction::A) | ||
} | ||
|
||
fn released(action_state: &ActionState<TestAction>) -> bool { | ||
action_state.released(TestAction::A) | ||
} | ||
|
||
fn just_released(action_state: &ActionState<TestAction>) -> bool { | ||
action_state.just_released(TestAction::A) | ||
} | ||
|
||
fn update(mut action_state: ActionState<TestAction>, action_data: Vec<ActionData>) { | ||
action_state.update(action_data); | ||
} | ||
|
||
fn criterion_benchmark(c: &mut Criterion) { | ||
let action_state = ActionState::<TestAction>::default(); | ||
|
||
c.bench_function("action_state_default", |b| { | ||
b.iter(|| ActionState::<TestAction>::default()) | ||
}); | ||
c.bench_function("pressed", |b| b.iter(|| pressed(&action_state))); | ||
c.bench_function("just_pressed", |b| b.iter(|| just_pressed(&action_state))); | ||
c.bench_function("released", |b| b.iter(|| released(&action_state))); | ||
c.bench_function("just_released", |b| b.iter(|| just_released(&action_state))); | ||
|
||
let action_data: Vec<ActionData> = TestAction::variants() | ||
.map(|_action| ActionData { | ||
state: ButtonState::JustPressed, | ||
value: 0.0, | ||
axis_pair: None, | ||
timing: Timing::default(), | ||
consumed: false, | ||
}) | ||
.collect(); | ||
|
||
c.bench_function("update", |b| { | ||
b.iter(|| update(action_state.clone(), action_data.clone())) | ||
}); | ||
} | ||
|
||
criterion_group!(benches, criterion_benchmark); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
use bevy::{ | ||
input::InputPlugin, | ||
prelude::{App, KeyCode}, | ||
}; | ||
use criterion::{black_box, criterion_group, criterion_main, Criterion}; | ||
use leafwing_input_manager::{ | ||
action_state::ActionData, | ||
input_streams::InputStreams, | ||
prelude::{ClashStrategy, InputMap, MockInput}, | ||
Actionlike, | ||
}; | ||
|
||
#[derive(Actionlike, Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
enum TestAction { | ||
A, | ||
B, | ||
C, | ||
D, | ||
E, | ||
F, | ||
G, | ||
H, | ||
I, | ||
J, | ||
} | ||
|
||
fn construct_input_map_from_iter() -> InputMap<TestAction> { | ||
black_box(InputMap::new([ | ||
(KeyCode::A, TestAction::A), | ||
(KeyCode::B, TestAction::B), | ||
(KeyCode::C, TestAction::C), | ||
(KeyCode::D, TestAction::D), | ||
(KeyCode::E, TestAction::E), | ||
(KeyCode::F, TestAction::F), | ||
(KeyCode::G, TestAction::G), | ||
(KeyCode::H, TestAction::H), | ||
(KeyCode::I, TestAction::I), | ||
(KeyCode::J, TestAction::J), | ||
])) | ||
} | ||
|
||
fn construct_input_map_from_chained_calls() -> InputMap<TestAction> { | ||
black_box( | ||
InputMap::default() | ||
.insert(KeyCode::A, TestAction::A) | ||
.insert(KeyCode::B, TestAction::B) | ||
.insert(KeyCode::C, TestAction::C) | ||
.insert(KeyCode::D, TestAction::D) | ||
.insert(KeyCode::E, TestAction::E) | ||
.insert(KeyCode::F, TestAction::F) | ||
.insert(KeyCode::G, TestAction::G) | ||
.insert(KeyCode::H, TestAction::H) | ||
.insert(KeyCode::I, TestAction::I) | ||
.insert(KeyCode::J, TestAction::J) | ||
.build(), | ||
) | ||
} | ||
|
||
fn which_pressed(input_streams: &InputStreams, clash_strategy: ClashStrategy) -> Vec<ActionData> { | ||
let input_map = construct_input_map_from_iter(); | ||
input_map.which_pressed(input_streams, clash_strategy) | ||
} | ||
|
||
pub fn criterion_benchmark(c: &mut Criterion) { | ||
c.bench_function("construct_input_map_from_iter", |b| { | ||
b.iter(|| construct_input_map_from_iter()) | ||
}); | ||
c.bench_function("construct_input_map_from_chained_calls", |b| { | ||
b.iter(|| construct_input_map_from_chained_calls()) | ||
}); | ||
let mut which_pressed_group = c.benchmark_group("which_pressed"); | ||
|
||
// Constructing our test app / input stream outside of the timed benchmark | ||
let mut app = App::new(); | ||
app.add_plugin(InputPlugin); | ||
app.send_input(KeyCode::A); | ||
app.send_input(KeyCode::B); | ||
app.update(); | ||
|
||
let input_streams = InputStreams::from_world(&app.world, None); | ||
|
||
for clash_strategy in ClashStrategy::variants() { | ||
which_pressed_group.bench_function(format!("{:?}", clash_strategy), |b| { | ||
b.iter(|| which_pressed(&input_streams, *clash_strategy)) | ||
}); | ||
} | ||
which_pressed_group.finish(); | ||
} | ||
|
||
criterion_group!(benches, criterion_benchmark); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters