Skip to content

Commit

Permalink
Add benchmark for ping1d and ping360
Browse files Browse the repository at this point in the history
  • Loading branch information
RaulTrombin committed Oct 4, 2024
1 parent 6d66765 commit ead2d29
Show file tree
Hide file tree
Showing 3 changed files with 279 additions and 0 deletions.
65 changes: 65 additions & 0 deletions .github/workflows/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,71 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./target/doc

bench:
needs: build
if: ${{ github.repository_owner == 'bluerobotics' }}
runs-on: raspbian-armv7-kernel-5.10.33
steps:
- uses: actions/checkout@master
- uses: dtolnay/rust-toolchain@stable
- name: Rust | Cache
uses: Swatinem/rust-cache@v2
with:
prefix-key: "rust-cache"
shared-key: "benchmark"
- name: Get previous benchmark data
run: |
echo "Fetching gh-pages branch"
git fetch origin gh-pages
echo "Checking out gh-pages branch"
git checkout gh-pages
if [ ! -d "cache" ]; then
echo "Cache folder does not exist, creating it"
mkdir cache
fi
echo "Copying data file from gh-pages to cache"
cp dev/cache/benchmark-data.json cache/benchmark-data.json || { echo "Failed to copy data file" ; exit 1; }
echo "Checking out current preivous branch"
git checkout -
- name: Cargo Bench
run: cargo bench --jobs 1 --bench bench -- --output-format bencher | tee output.txt || { echo "Benchmark failed"; exit 1; }
- name: Compare results & store cached results
uses: benchmark-action/[email protected]
with:
tool: 'cargo'
output-file-path: output.txt
summary-always: true
alert-threshold: "130%"
fail-on-alert: true
external-data-json-path: ./cache/benchmark-data.json
skip-fetch-gh-pages: "true"
- name: Update data file
if: ${{ github.ref == 'refs/heads/master' }}
run: |
git config user.name "GitHub Actions Bot"
git config user.email "[email protected]"
git fetch origin gh-pages
git checkout gh-pages
if [ ! -d "dev/cache" ]; then
echo "Cache folder does not exist, creating it"
mkdir -p dev/cache
fi
cp cache/benchmark-data.json dev/cache/benchmark-data.json
tree cache
git add dev/cache/benchmark-data.json
git commit -m "Update benchmark-data file"
git push origin gh-pages
deploy:
needs: build
runs-on: ubuntu-latest
Expand Down
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ serde_bytes = "0.11"
[dev-dependencies]
tracing-test = "0.2.4"
udp-stream = "0.0.12"
criterion = { version = "0.5.1", features = ["html_reports", "async_tokio"] }

[build-dependencies]
convert_case = "0.6.0"
Expand All @@ -38,3 +39,7 @@ serde_json = "1.0.64"
[features]
local_runner = []
default = ["serde"]

[[bench]]
name = "bench"
harness = false
209 changes: 209 additions & 0 deletions benches/bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
use bluerobotics_ping::{
device::{Ping1D, Ping360, PingDevice},
message::MessageInfo,
ping1d::{self, ProfileStruct},
Messages,
};
use criterion::black_box;
use criterion::{criterion_group, criterion_main, Criterion};
use std::time::Instant;
use std::{net::SocketAddr, str::FromStr};
use tokio::runtime::Runtime;
use tokio_serial::{Error, SerialPort, SerialPortBuilderExt};
use udp_stream::UdpStream;

fn rt() -> Runtime {
tokio::runtime::Builder::new_current_thread()
.enable_all()
.worker_threads(1)
.thread_name("criterion-tokio-rt")
.build()
.unwrap()
}

async fn create_ping1d_usb() -> Ping1D {
let port = tokio_serial::new("/dev/ttyUSB0".to_string(), 115200)
.open_native_async()
.map_err(|e| {
eprintln!("Error opening serial port: {}", e);
e
})
.unwrap();
port.clear(tokio_serial::ClearBuffer::All).unwrap();

Ping1D::new(port)
}

async fn create_ping360_udp() -> Ping360 {
let socket_addr = SocketAddr::from_str(&format!("192.168.1.197:12345"))
.map_err(|e| {
eprintln!("Error parsing UDP address: {}", e);
e
})
.unwrap();
let port = UdpStream::connect(socket_addr)
.await
.map_err(|e| {
eprintln!("Error connecting to UDP socket: {}", e);
e
})
.unwrap();
Ping360::new(port)
}

async fn receive_10_profiles(
mut subscribed: tokio::sync::broadcast::Receiver<bluerobotics_ping::message::ProtocolMessage>,
) -> Result<(), Error> {
let mut profile_struct_vector: Vec<ProfileStruct> = Vec::new();
for _i in 1..10 {
let received = subscribed.recv().await;

match received {
Ok(msg) => {
if msg.message_id == bluerobotics_ping::ping1d::ProfileStruct::id() {
match Messages::try_from(&msg) {
Ok(Messages::Ping1D(ping1d::Messages::Profile(answer))) => {
profile_struct_vector.push(answer)
}
_ => panic!(),
}
}
}
Err(_e) => {
panic!()
}
}
}
Ok(())
}

fn ping1d_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("Ping1D");
group.sample_size(10); // Reduced sample size
group.measurement_time(std::time::Duration::from_secs(60)); // Increased measurement time

macro_rules! bench {
($bench_fn:ident($($arg:tt)*)) => {
group.bench_function(stringify!($bench_fn), move |b| {
b.to_async(rt()).iter_custom(|iters| async move {
let ping1d = create_ping1d_usb().await;

ping1d.continuous_stop(bluerobotics_ping::ping1d::ProfileStruct::id())
.await
.unwrap();

tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;

let mut total_duration = std::time::Duration::new(0, 0);
for _i in 0..iters {
let start = Instant::now();
let result = black_box(ping1d.$bench_fn($($arg)*).await);
total_duration += start.elapsed();
result.unwrap();
}
total_duration
})
});
}
}

// Get Methods
bench!(profile());
// bench!(ping_interval());
// bench!(transmit_duration());
// bench!(range());
// bench!(speed_of_sound());
// bench!(firmware_version());
// bench!(mode_auto());
// bench!(distance_simple());
// bench!(pcb_temperature());
// bench!(ping_enable());
// bench!(general_info());
// bench!(distance());
// bench!(processor_temperature());
// bench!(voltage_5());
// bench!(gain_setting());
// bench!(device_id());

// Custom - receive 10 profile packages
group.bench_function("Receive 10 profiles", move |b| {
b.to_async(rt()).iter_custom(|iters| async move {
let ping1d = create_ping1d_usb().await;

ping1d
.continuous_start(bluerobotics_ping::ping1d::ProfileStruct::id())
.await
.unwrap();

let mut total_duration = std::time::Duration::new(0, 0);
for _i in 0..iters {
let start = Instant::now();
black_box(receive_10_profiles(ping1d.subscribe()).await.unwrap());
total_duration += start.elapsed();
}

ping1d
.continuous_stop(bluerobotics_ping::ping1d::ProfileStruct::id())
.await
.unwrap();

total_duration
})
});

group.finish();
}

fn ping360_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("Ping360");
group.sample_size(10);
group.measurement_time(std::time::Duration::from_secs(60));

macro_rules! bench360 {
($bench_fn:ident($($arg:tt)*)) => {
group.bench_function(stringify!($bench_fn), move |b| {
b.to_async(rt()).iter_custom(|iters| async move {
let ping360 = create_ping360_udp().await;
ping360.reset(0,0).await.unwrap();

let mut total_duration = std::time::Duration::new(0, 0);
for _i in 0..iters {
let start = Instant::now();
let result = black_box(ping360.$bench_fn($($arg)*).await);
total_duration += start.elapsed();
result.unwrap();
}
total_duration
})
});
}
}

let mode: u8 = 1;
let gain_setting: u8 = 0;
let angle: u16 = 360;
let transmit_duration: u16 = 7;
let sample_period: u16 = 80;
let transmit_frequency: u16 = 700;
let number_of_samples: u16 = 1200;
let transmit: u8 = 1;

// Get Methods
bench360!(transducer(
mode,
gain_setting,
angle,
transmit_duration,
sample_period,
transmit_frequency,
number_of_samples,
transmit,
0,
));
bench360!(motor_off());

group.finish();
}

criterion_group!(benches, ping1d_benchmark, ping360_benchmark);
criterion_main!(benches);

0 comments on commit ead2d29

Please sign in to comment.