Sling Academy
Home/Rust/Running Examples and Benchmarks with Cargo for Rust Projects

Running Examples and Benchmarks with Cargo for Rust Projects

Last updated: January 04, 2025

When working on Rust projects, managing dependencies, compiling, running tests, and benchmarks is efficiently handled by Cargo, Rust's package manager and build system. In this article, we'll look at how to use Cargo to run examples and benchmarks within your Rust projects to optimize performance and ensure smooth execution.

Running Examples

Examples provide a useful way of demonstrating or testing functionality in a Rust project. They reside in the examples directory in your project and are a great way to give an introduction or specific walkthrough of your project's capabilities.

Creating Example Files

To start, create an examples directory at the root of your project if it doesn't already exist:

mkdir examples

Next, add a new Rust file inside this directory. For instance, you can create a file called example_name.rs:

touch examples/example_name.rs

Within example_name.rs, you can write Rust code that showcases some functionality. Here’s a simple example:

fn main() {
    println!("Hello from the example!");
}

Running an Example

To run your example using Cargo, use the following command:

cargo run --example example_name

This will compile and execute the example_name.rs file, producing output in your terminal.

Running Benchmarks

Benchmarks are a crucial part of performance tuning in Rust projects. The default path for benchmarks is the benches directory in your project.

Setting Up Benchmark Files

Begin by including the following dev-dependencies in your Cargo.toml file:

[dev-dependencies]
criterion = "0.4.0"

Criterion.rs is a popular choice for benchmarks given its capabilities and ease of use.

Create a benches directory in the root of your project:

mkdir benches

Add your first benchmark file, e.g., benchmark_name.rs:

touch benches/benchmark_name.rs

Include the following Rust code as a basic benchmark using Criterion:

use criterion::{criterion_group, criterion_main, Criterion};

fn benchmark_example(c: &mut Criterion) {
    c.bench_function("expensive_calculation", |b| b.iter(|| expensive_calculation()));
}

criterion_group!(benches, benchmark_example);
criterion_main!(benches);

fn expensive_calculation() {
    // Imagine this is some complex computation
    let mut a = 0;
    for i in 1..1000 {
        a += i;
    }
}

Running Benchmarks

To execute the benchmarks, use the command:

cargo bench

This command runs all benchmarks found in the benches directory. You’ll see detailed timing data for each benchmark, which is invaluable for identifying bottlenecks.

Conclusion

Using Cargo to manage examples and benchmarks is an excellent way to maintain a clear structure in your Rust projects. Examples help others understand and utilize your project effectively, while benchmarks ensure that your code performs optimally. Regularly running both is recommended as part of a comprehensive development workflow to maintain the quality and efficiency of your application. Rust's ecosystem provides excellent tools, like Cargo, to streamline these tasks, enhancing productivity and code performance.

Next Article: Leveraging the Cargo.lock File for Repeatable Builds in Rust

Previous Article: Testing in Rust: Using Integration Tests in a Separate Tests Folder

Series: Packages, Crates, and Modules in Rust

Rust

You May Also Like

  • E0557 in Rust: Feature Has Been Removed or Is Unavailable in the Stable Channel
  • Network Protocol Handling Concurrency in Rust with async/await
  • Using the anyhow and thiserror Crates for Better Rust Error Tests
  • Rust - Investigating partial moves when pattern matching on vector or HashMap elements
  • Rust - Handling nested or hierarchical HashMaps for complex data relationships
  • Rust - Combining multiple HashMaps by merging keys and values
  • Composing Functionality in Rust Through Multiple Trait Bounds
  • E0437 in Rust: Unexpected `#` in macro invocation or attribute
  • Integrating I/O and Networking in Rust’s Async Concurrency
  • E0178 in Rust: Conflicting implementations of the same trait for a type
  • Utilizing a Reactor Pattern in Rust for Event-Driven Architectures
  • Parallelizing CPU-Intensive Work with Rust’s rayon Crate
  • Managing WebSocket Connections in Rust for Real-Time Apps
  • Downloading Files in Rust via HTTP for CLI Tools
  • Mocking Network Calls in Rust Tests with the surf or reqwest Crates
  • Rust - Designing advanced concurrency abstractions using generic channels or locks
  • Managing code expansion in debug builds with heavy usage of generics in Rust
  • Implementing parse-from-string logic for generic numeric types in Rust
  • Rust.- Refining trait bounds at implementation time for more specialized behavior