From 07afdff794fdb3967197d217346b03bd6b436ef9 Mon Sep 17 00:00:00 2001 From: LIAUD Corentin Date: Sun, 17 Nov 2024 18:05:57 +0100 Subject: [PATCH 1/3] feat: add benches --- adb_client/Cargo.toml | 9 ++++ benches/benchmark_adb_push.rs | 94 +++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 benches/benchmark_adb_push.rs diff --git a/adb_client/Cargo.toml b/adb_client/Cargo.toml index cf33e94..37c9010 100644 --- a/adb_client/Cargo.toml +++ b/adb_client/Cargo.toml @@ -30,3 +30,12 @@ serde = { version = "1.0.210", features = ["derive"] } serde_repr = { version = "0.1.19" } sha1 = { version = "0.10.6", features = ["oid"] } thiserror = { version = "2.0.1" } + +[dev-dependencies] +anyhow = { version = "1.0.93" } +criterion = { version = "0.5.1" } # Used for benchmarks + +[[bench]] +harness = false +name = "benchmark_adb_push" +path = "../benches/benchmark_adb_push.rs" diff --git a/benches/benchmark_adb_push.rs b/benches/benchmark_adb_push.rs new file mode 100644 index 0000000..a2b76a1 --- /dev/null +++ b/benches/benchmark_adb_push.rs @@ -0,0 +1,94 @@ +use adb_client::ADBServer; +use anyhow::Result; +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; +use rand::{thread_rng, Rng}; +use std::fs::File; +use std::io::Write; +use std::process::Command; +use std::time::Duration; + +const LOCAL_TEST_FILE_PATH: &str = "test_file.bin"; +const REMOTE_TEST_FILE_PATH: &str = "/data/local/tmp/test_file.bin"; + + +/// Generate random test file with given size +fn generate_test_file(size_in_bytes: usize) -> Result<()> { + let mut test_file = File::create(LOCAL_TEST_FILE_PATH)?; + + let mut rng = thread_rng(); + + const BUFFER_SIZE: usize = 64 * 1024; + let mut buffer = [0u8; BUFFER_SIZE]; + let mut remaining_bytes = size_in_bytes; + + while remaining_bytes > 0 { + let bytes_to_write = remaining_bytes.min(BUFFER_SIZE); + rng.fill(&mut buffer[..bytes_to_write]); + test_file.write_all(&buffer[..bytes_to_write])?; + remaining_bytes -= bytes_to_write; + } + + Ok(()) +} + +/// Use `adb_client` crate to push a file on device +fn bench_adb_client_push() -> Result<()> { + let mut client = ADBServer::default(); + let mut device = client.get_device()?; + let f = File::open(LOCAL_TEST_FILE_PATH)?; + Ok(device.push(f, REMOTE_TEST_FILE_PATH)?) +} + +/// Use standard `adb` command ti push a file on device +fn bench_adb_push_command() -> Result<()> { + let output = Command::new("adb") + .arg("push") + .arg(LOCAL_TEST_FILE_PATH) + .arg(REMOTE_TEST_FILE_PATH) + .output()?; + + if !output.status.success() { + eprintln!("error while starting adb push command"); + } + Ok(()) +} + +/// Main benchmark function +fn benchmark_adb_push(c: &mut Criterion) { + for (file_size, sample_size) in [ + // (10 * 1024 * 1024, 100), // 10MB -> 100 iterations + // (500 * 1024 * 1024, 50), // 500MB -> 50 iterations + (1000 * 1024 * 1024, 20), // 1GB -> 20 iterations + ] { + eprintln!( + "Benchmarking file_size={} and sample_size={}", + file_size, sample_size + ); + + generate_test_file(file_size).expect("Cannot generate test file"); + + let mut group = c.benchmark_group("ADB Push Benchmark"); + group.sample_size(sample_size); + + group.bench_function(BenchmarkId::new("adb_client", "push"), |b| { + b.iter(|| { + bench_adb_client_push().expect("Error while benchmarking adb_client push"); + }); + }); + + group.bench_function(BenchmarkId::new("adb", "push"), |b| { + b.iter(|| { + bench_adb_push_command().expect("Error while benchmarking adb push command"); + }); + }); + + group.finish(); + } +} + +criterion_group!( + name = benches; + config = Criterion::default().measurement_time(Duration::from_secs(1000)); + targets = benchmark_adb_push +); +criterion_main!(benches); From 617f7ba8f52d9f56b58d692af67e6b8b02d9a99d Mon Sep 17 00:00:00 2001 From: LIAUD Corentin Date: Fri, 29 Nov 2024 15:35:18 +0100 Subject: [PATCH 2/3] fix: fmt --- benches/benchmark_adb_push.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/benches/benchmark_adb_push.rs b/benches/benchmark_adb_push.rs index a2b76a1..cd811b4 100644 --- a/benches/benchmark_adb_push.rs +++ b/benches/benchmark_adb_push.rs @@ -10,7 +10,6 @@ use std::time::Duration; const LOCAL_TEST_FILE_PATH: &str = "test_file.bin"; const REMOTE_TEST_FILE_PATH: &str = "/data/local/tmp/test_file.bin"; - /// Generate random test file with given size fn generate_test_file(size_in_bytes: usize) -> Result<()> { let mut test_file = File::create(LOCAL_TEST_FILE_PATH)?; From d2dde3c6d03d9a99fb43db1b23f698be2cc2eacb Mon Sep 17 00:00:00 2001 From: LIAUD Corentin Date: Fri, 29 Nov 2024 15:39:33 +0100 Subject: [PATCH 3/3] feat: improve benchmarks --- benches/benchmark_adb_push.rs | 50 ++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/benches/benchmark_adb_push.rs b/benches/benchmark_adb_push.rs index cd811b4..a860ac9 100644 --- a/benches/benchmark_adb_push.rs +++ b/benches/benchmark_adb_push.rs @@ -1,4 +1,4 @@ -use adb_client::ADBServer; +use adb_client::{ADBDeviceExt, ADBServer, ADBUSBDevice}; use anyhow::Result; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use rand::{thread_rng, Rng}; @@ -38,6 +38,14 @@ fn bench_adb_client_push() -> Result<()> { Ok(device.push(f, REMOTE_TEST_FILE_PATH)?) } +/// Use `adb_client` crate to push a file on device using an USB device. +/// Only one android device must be connected when launching this benchmark as we're using `autodetect()` method. +fn bench_adb_client_push_over_usb() -> Result<()> { + let mut device = ADBUSBDevice::autodetect()?; + let f = File::open(LOCAL_TEST_FILE_PATH)?; + Ok(device.push(f, REMOTE_TEST_FILE_PATH)?) +} + /// Use standard `adb` command ti push a file on device fn bench_adb_push_command() -> Result<()> { let output = Command::new("adb") @@ -52,8 +60,41 @@ fn bench_adb_push_command() -> Result<()> { Ok(()) } -/// Main benchmark function +/// benchmarking `adb push INPUT DEST` and adb_client `ADBServerDevice.push(INPUT, DEST)` fn benchmark_adb_push(c: &mut Criterion) { + for (file_size, sample_size) in [ + (10 * 1024 * 1024, 100), // 10MB -> 100 iterations + (500 * 1024 * 1024, 50), // 500MB -> 50 iterations + (1000 * 1024 * 1024, 20), // 1GB -> 20 iterations + ] { + eprintln!( + "Benchmarking file_size={} and sample_size={}", + file_size, sample_size + ); + + generate_test_file(file_size).expect("Cannot generate test file"); + + let mut group = c.benchmark_group("ADB Push Benchmark"); + group.sample_size(sample_size); + + group.bench_function(BenchmarkId::new("adb_client", "push"), |b| { + b.iter(|| { + bench_adb_client_push().expect("Error while benchmarking adb_client push"); + }); + }); + + group.bench_function(BenchmarkId::new("adb", "push"), |b| { + b.iter(|| { + bench_adb_push_command().expect("Error while benchmarking adb push command"); + }); + }); + + group.finish(); + } +} + +/// benchmarking `adb push INPUT DEST` and adb_client `ADBUSBDevice.push(INPUT, DEST)` +fn benchmark_adb_push_over_usb(c: &mut Criterion) { for (file_size, sample_size) in [ // (10 * 1024 * 1024, 100), // 10MB -> 100 iterations // (500 * 1024 * 1024, 50), // 500MB -> 50 iterations @@ -71,7 +112,8 @@ fn benchmark_adb_push(c: &mut Criterion) { group.bench_function(BenchmarkId::new("adb_client", "push"), |b| { b.iter(|| { - bench_adb_client_push().expect("Error while benchmarking adb_client push"); + bench_adb_client_push_over_usb() + .expect("Error while benchmarking adb_client push over USB"); }); }); @@ -88,6 +130,6 @@ fn benchmark_adb_push(c: &mut Criterion) { criterion_group!( name = benches; config = Criterion::default().measurement_time(Duration::from_secs(1000)); - targets = benchmark_adb_push + targets = benchmark_adb_push, benchmark_adb_push_over_usb ); criterion_main!(benches);