From ac42aedc1188e3136e4692f871e43b6a8bf3ad17 Mon Sep 17 00:00:00 2001 From: Patrice Billaut <57354406+pbillaut@users.noreply.github.com> Date: Tue, 24 Sep 2024 22:17:10 +0200 Subject: [PATCH] chore(memory-profiling): add option for macos (#18) --- Makefile.toml | 25 +++++++++++++++++++++++-- README.md | 31 +++++++++++++++++++++++++++++-- src/main.rs | 11 ++++++++++- 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/Makefile.toml b/Makefile.toml index 25561dd..46fa39d 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -11,7 +11,8 @@ command = "cargo" args = ["build", "--profile", "${BUILD_PROFILE_PERF}"] [tasks.heaptrack] -description = "Run heaptrack" +description = "Profile memory usage with heaptrack (Linux)" +condition = { platforms = ["linux"] } dependencies = ["build-perf"] script = ''' SIZE="${1:-10K}" @@ -41,5 +42,25 @@ fi OUTPUT_FILE="${CARGO_MAKE_WORKING_DIRECTORY}/heaptrack.${CARGO_MAKE_CRATE_NAME}.${SIZE}.${TAG}" BINARY="${CARGO_MAKE_CRATE_TARGET_DIRECTORY}/${BUILD_PROFILE_PERF}/${CARGO_MAKE_CRATE_NAME}" -heaptrack --output "${OUTPUT_FILE}" "${BINARY}" "${SAMPLE_FILE}" +heaptrack --output "${OUTPUT_FILE}" "${BINARY}" --silent "${SAMPLE_FILE}" ''' + +[tasks.instruments] +description = "Profile memory usage with instruments (macOS)" +condition = { platforms = ["mac"] } +script = ''' +SIZE="${1:-10K}" +SAMPLE_FILE="${BENCHES_DATA_DIR}/activities_${SIZE}.csv" +if [ ! -f "$SAMPLE_FILE" ]; then + echo "ERROR: File '${SAMPLE_FILE}' does not exist." + echo + echo "Available sample files in '${DATA_DIR}':" + for file in ${BENCHES_DATA_DIR}/activities_*.csv; do + echo "• $(basename "$file")" + done + echo + exit 1 +fi + +cargo instruments --profile perf -t Allocations -- --silent "${SAMPLE_FILE}" +''' \ No newline at end of file diff --git a/README.md b/README.md index 04a7f91..f2f570f 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,28 @@ A simple toy payment processor. +## Profiling + +### Memory + +#### Linux + +To profile memory usage on Linux with [heaptrack][tool:heaptrack], run + +```shell +cargo make heaptrack [1K|10K] +``` + +#### macOS + +To profile memory usage on macOS with [Instruments][tool:instruments], +install [cargo-instruments][tool:cargo-instruments] and +run + +```shell +cargo make instruments [1K|10K] +``` + ## A Note on Parsing In parsing a CSV file containing different types of records, such as transactions and dispute events, using separate @@ -49,9 +71,14 @@ As above, since no specific performance target has been set, there is no strong that rely on native floating-point types. The advantages provided by [`rust_decimal`][crate:rust_decimal], particularly in terms of precision and error avoidance, outweigh the potential performance gains from using floats. -[type:decimal]: https://docs.rs/rust_decimal/latest/rust_decimal/struct.Decimal.html - [crate:csv]: https://docs.rs/csv/latest [crate:rust_decimal]: https://docs.rs/rust_decimal/latest +[tool:cargo-instruments]: https://crates.io/crates/cargo-instruments + +[tool:heaptrack]: https://github.com/KDE/heaptrack + +[tool:instruments]: https://help.apple.com/instruments/mac/current + +[type:decimal]: https://docs.rs/rust_decimal/latest/rust_decimal/struct.Decimal.html \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index d3268f1..1a3160d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use anyhow::Context; use clap::{Parser, ValueHint}; use payment_processor::processor::Processor; use payment_processor::processors::csv::CsvProcessor; +use std::io::Write; use std::{fs::File, io, path::PathBuf}; use tracing_subscriber::EnvFilter; @@ -13,6 +14,14 @@ struct Cli { /// Supported file formats: CSV #[arg(value_hint = ValueHint::FilePath)] path: PathBuf, + + /// Whether to suppress printing the results to stdout. + #[clap(long, action)] + silent: bool, +} + +fn output(silent: bool) -> Box { + if silent { Box::new(io::sink()) } else { Box::new(io::stdout()) } } fn main() -> Result<(), anyhow::Error> { @@ -24,6 +33,6 @@ fn main() -> Result<(), anyhow::Error> { let cli = Cli::parse(); let file = File::open(&cli.path).context("unable to open file input file")?; - let mut processor = CsvProcessor::try_new(file, io::stdout())?; + let mut processor = CsvProcessor::try_new(file, output(cli.silent))?; processor.process().context("processing input file failed") }