Skip to content

Commit

Permalink
docs: improve doc comments and readme (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
pbillaut authored Sep 15, 2024
1 parent c7d7d4d commit 236b612
Show file tree
Hide file tree
Showing 90 changed files with 18,096 additions and 17 deletions.
56 changes: 56 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,57 @@
# Payment Processor

A simple toy payment processor.

## A Note on Parsing

In parsing a CSV file containing different types of records, such as transactions and dispute events, using separate
structs for each type, united into an enum (see [`AccountActivity`](src/account_activity.rs)), offers significant
advantages over a single struct with optional fields.

Although the [csv][crate:csv] crate doesn't natively support parsing into this type of data structure, the
effort to adapt the deserializer is worthwhile. It enhances safety, reduces runtime errors, and improves code clarity
in the long term.

### Type-Level Invariants

Separate structs ensure that each record type only contains its relevant fields. A transaction struct will always have
fields transaction id, client id and amount, whereas a dispute event will only include transaction id and client id.
This enforces clear, type-safe invariants, preventing errors caused by missing or irrelevant fields.

### Compile-Time Safety

The Rust compiler can enforce the correctness of the data structures, eliminating the need for checking `Options` and
reducing runtime errors. Each record type is guaranteed to have only the fields it needs, providing strong compile-time
guarantees.

## Performance

As no specific performance target has been set, the processor is primarily optimized for robustness and convenience.
However, performance has still been considered where appropriate to avoid missing obvious optimizations.

### Parsing

As expected, the slowest part of data processing is CSV file parsing, primarily due to I/O waiting times. The commonly
used [`csv`][crate:csv] crate does not support asynchronous file reading, limiting optimization potential in
this area. While alternative crates with async support exist, they require further evaluation before adoption.

### Calculations

Although [benchmarks](docs/bench-reports/decimals) indicate that the use of the [`Decimal`][type:decimal] type of the
[`rust_decimal`][crate:rust_decimal] crate results in approximately a 20% performance decrease, its
benefits make it a sensible choice for financial calculations.

The crate ensures there are no rounding errors, which is crucial when dealing with financial data. Additionally, common
issues associated with floating point types, such as NaN, infinite, or subnormal values, are avoided since decimals
inherently cannot represent these states, eliminating the need for additional checks.

As above, since no specific performance target has been set, there is no strong justification for exploring alternatives
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

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"group_id":"CsvReader::iter","function_id":null,"value_str":"1000","throughput":{"Elements":1000},"full_id":"CsvReader::iter/1000","directory_name":"CsvReader__iter/1000","title":"CsvReader::iter/1000"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4491619.6754583325,"upper_bound":4521767.687083333},"point_estimate":4506091.455833332,"standard_error":7737.51318485144},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4464704.833333333,"upper_bound":4480699.625},"point_estimate":4470373.291666667,"standard_error":4088.840403213924},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":24354.731542617545,"upper_bound":53245.04836846232},"point_estimate":36699.53844845364,"standard_error":7391.836028550336},"slope":null,"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":63242.09304287018,"upper_bound":89603.92681349863},"point_estimate":77261.5906523178,"standard_error":6704.360437807731}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"sampling_mode":"Flat","iters":[12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0],"times":[55321583.0,55468125.0,55543708.0,55657875.0,55604167.0,57329125.0,55301291.0,53456750.0,53243917.0,55472167.0,54040292.0,53346333.0,53310291.0,53596541.0,53435292.0,54014750.0,53465250.0,53350750.0,54261125.0,55425708.0,53304459.0,53258583.0,53284583.0,53238833.0,53547875.0,53706583.0,53677167.0,53602334.0,54888833.0,55045875.0,53667375.0,53546125.0,53381417.0,53270791.0,53712416.0,53240750.0,53220500.0,54360166.0,54934833.0,53531584.0,53327542.0,53258917.0,53618875.0,53579875.0,53311833.0,53494083.0,53613708.0,53648084.0,53640875.0,53611542.0,53797292.0,54376333.0,54088333.0,53818500.0,53524375.0,53750750.0,53981334.0,55483584.0,53421042.0,53263667.0,53688375.0,53374792.0,53386416.0,53568958.0,53313625.0,53313292.0,55527666.0,54401667.0,53348542.0,53709125.0,53480042.0,53462375.0,53796792.0,55383667.0,55786750.0,55748167.0,56809041.0,54270833.0,53864833.0,53742791.0,53428042.0,53422209.0,53431542.0,53662584.0,53431167.0,54786166.0,55251833.0,53583958.0,54291208.0,53794000.0,53500750.0,53592083.0,55642791.0,55028500.0,56098625.0,56158500.0,53859708.0,53576458.0,53570458.0,53544750.0]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[4214816.125,4333718.40625,4650791.15625,4769693.4375]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.20217606299801563,"upper_bound":0.21308717355640241},"point_estimate":0.20745347520973834,"standard_error":0.002789667941237223},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.20435880603789605,"upper_bound":0.20915148860722765},"point_estimate":0.20611924480910648,"standard_error":0.0012521807604802837}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"group_id":"CsvReader::iter","function_id":null,"value_str":"1000","throughput":{"Elements":1000},"full_id":"CsvReader::iter/1000","directory_name":"CsvReader__iter/1000","title":"CsvReader::iter/1000"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4491619.6754583325,"upper_bound":4521767.687083333},"point_estimate":4506091.455833332,"standard_error":7737.51318485144},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4464704.833333333,"upper_bound":4480699.625},"point_estimate":4470373.291666667,"standard_error":4088.840403213924},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":24354.731542617545,"upper_bound":53245.04836846232},"point_estimate":36699.53844845364,"standard_error":7391.836028550336},"slope":null,"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":63242.09304287018,"upper_bound":89603.92681349863},"point_estimate":77261.5906523178,"standard_error":6704.360437807731}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"sampling_mode":"Flat","iters":[12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0],"times":[55321583.0,55468125.0,55543708.0,55657875.0,55604167.0,57329125.0,55301291.0,53456750.0,53243917.0,55472167.0,54040292.0,53346333.0,53310291.0,53596541.0,53435292.0,54014750.0,53465250.0,53350750.0,54261125.0,55425708.0,53304459.0,53258583.0,53284583.0,53238833.0,53547875.0,53706583.0,53677167.0,53602334.0,54888833.0,55045875.0,53667375.0,53546125.0,53381417.0,53270791.0,53712416.0,53240750.0,53220500.0,54360166.0,54934833.0,53531584.0,53327542.0,53258917.0,53618875.0,53579875.0,53311833.0,53494083.0,53613708.0,53648084.0,53640875.0,53611542.0,53797292.0,54376333.0,54088333.0,53818500.0,53524375.0,53750750.0,53981334.0,55483584.0,53421042.0,53263667.0,53688375.0,53374792.0,53386416.0,53568958.0,53313625.0,53313292.0,55527666.0,54401667.0,53348542.0,53709125.0,53480042.0,53462375.0,53796792.0,55383667.0,55786750.0,55748167.0,56809041.0,54270833.0,53864833.0,53742791.0,53428042.0,53422209.0,53431542.0,53662584.0,53431167.0,54786166.0,55251833.0,53583958.0,54291208.0,53794000.0,53500750.0,53592083.0,55642791.0,55028500.0,56098625.0,56158500.0,53859708.0,53576458.0,53570458.0,53544750.0]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[4214816.125,4333718.40625,4650791.15625,4769693.4375]
Loading

0 comments on commit 236b612

Please sign in to comment.