The project follows a modular, decoupled architecture in .NET 10 designed for testability, performance analysis, and clean code practices:
-
Abstraction (
ISortAlgorithm<T>): All sorting implementations implement a generic interface with the constraintwhere T : IComparable<T>, ensuring strict typing and support for any comparable data type (integers, strings, custom objects). -
In-Place vs. Auxiliary Memory: Algorithms are implemented adhering to their theoretical spatial boundaries (e.g.,
$O(1)$ space for QuickSort/HeapSort,$O(N)$ auxiliary allocation for MergeSort). - Unit Testing (xUnit): Full coverage including edge cases (already sorted arrays, empty arrays, duplicate values, negative numbers, and string sorting).
-
Automated Benchmarking: Integrated with BenchmarkDotNet for precision CPU cycle profiling and Garbage Collector (
MemoryDiagnoser) memory tracking.
The benchmarks were executed under the following environment:
- Tool: BenchmarkDotNet v0.15.8
- Runtime: .NET 10.0 (X64 RyuJIT x86-64-v3)
- Dataset: 1,000 randomly generated integers (
N = 1000)
| Method | N | Mean | Error | StdDev | Gen0 | Gen1 | Allocated Memory |
|---|---|---|---|---|---|---|---|
| QuickSort | 1000 | 16.43 µs | 0.322 µs | 0.501 µs | 0.4578 | - | 3.93 KB |
| HeapSort | 1000 | 26.82 µs | 0.525 µs | 0.769 µs | 0.4578 | - | 3.93 KB |
| MergeSort | 1000 | 36.85 µs | 0.571 µs | 0.445 µs | 11.4746 | 0.1221 | 94.07 KB |
| BubbleSort | 1000 | 1,677.34 µs | 33.043 µs | 62.868 µs | - | - | 3.93 KB |
Note: The baseline 3.93 KB allocation across all methods corresponds to the initial dataset clone required for isolated execution per iteration.
- QuickSort (Top Performance - 16.43 µs): Outperformed all algorithms (~102x faster than BubbleSort). Its contiguous array partitioning maximizes CPU L1/L2 cache locality, minimizing cache misses.
-
HeapSort (Guaranteed
$O(1)$ Auxiliary Space - 26.82 µs): Achieved steady$O(N \log N)$ execution without incurring Garbage Collector overhead (0GC collections), making it optimal for memory-constrained or real-time environments. -
MergeSort (Memory Trade-off - 36.85 µs & 94.07 KB Allocated): Demonstrated guaranteed
$O(N \log N)$ stability, but required auxiliary array allocations during the merge phases, triggering Garbage Collector passes (Gen0/Gen1). -
BubbleSort (Baseline Comparison - 1.67 ms): Confirmed theoretical
$O(N^2)$ quadratic degradation, serving as a baseline for algorithmic optimization.## 📐 Architecture & Design Principles
The project follows a modular, decoupled architecture in .NET 10 designed for testability, performance analysis, and clean code practices:
-
Abstraction (
ISortAlgorithm<T>): All sorting implementations implement a generic interface with the constraintwhere T : IComparable<T>, ensuring strict typing and support for any comparable data type (integers, strings, custom objects). -
In-Place vs. Auxiliary Memory: Algorithms are implemented adhering to their theoretical spatial boundaries (e.g.,
$O(1)$ space for QuickSort/HeapSort,$O(N)$ auxiliary allocation for MergeSort). - Unit Testing (xUnit): Full coverage including edge cases (already sorted arrays, empty arrays, duplicate values, negative numbers, and string sorting).
-
Automated Benchmarking: Integrated with BenchmarkDotNet for precision CPU cycle profiling and Garbage Collector (
MemoryDiagnoser) memory tracking.
The benchmarks were executed under the following environment:
- Tool: BenchmarkDotNet v0.15.8
- Runtime: .NET 10.0 (X64 RyuJIT x86-64-v3)
- Dataset: 1,000 randomly generated integers (
N = 1000)
| Method | N | Mean | Error | StdDev | Gen0 | Gen1 | Allocated Memory |
|---|---|---|---|---|---|---|---|
| QuickSort | 1000 | 16.43 µs | 0.322 µs | 0.501 µs | 0.4578 | - | 3.93 KB |
| HeapSort | 1000 | 26.82 µs | 0.525 µs | 0.769 µs | 0.4578 | - | 3.93 KB |
| MergeSort | 1000 | 36.85 µs | 0.571 µs | 0.445 µs | 11.4746 | 0.1221 | 94.07 KB |
| BubbleSort | 1000 | 1,677.34 µs | 33.043 µs | 62.868 µs | - | - | 3.93 KB |
Note: The baseline 3.93 KB allocation across all methods corresponds to the initial dataset clone required for isolated execution per iteration.
- QuickSort (Top Performance - 16.43 µs): Outperformed all algorithms (~102x faster than BubbleSort). Its contiguous array partitioning maximizes CPU L1/L2 cache locality, minimizing cache misses.
-
HeapSort (Guaranteed
$O(1)$ Auxiliary Space - 26.82 µs): Achieved steady$O(N \log N)$ execution without incurring Garbage Collector overhead (0GC collections), making it optimal for memory-constrained or real-time environments. -
MergeSort (Memory Trade-off - 36.85 µs & 94.07 KB Allocated): Demonstrated guaranteed
$O(N \log N)$ stability, but required auxiliary array allocations during the merge phases, triggering Garbage Collector passes (Gen0/Gen1). -
BubbleSort (Baseline Comparison - 1.67 ms): Confirmed theoretical
$O(N^2)$ quadratic degradation, serving as a baseline for algorithmic optimization.