Skip to content

Commit 0762f00

Browse files
committed
docs: update performance data and clarify benchmark context in README.md
1 parent a1da02a commit 0762f00

1 file changed

Lines changed: 10 additions & 10 deletions

File tree

‎README.md‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
[![PHP](https://img.shields.io/badge/PHP-%5E8.4-777BB4?logo=php&logoColor=white)](https://packagist.org/packages/std-out/simple-data-objects)
99
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
1010

11-
**Lightweight, attribute-driven DTOs for PHP 8.4+ — up to 37× faster hydration and serialization than the most popular alternative, zero reflection at runtime.**
11+
**Lightweight, attribute-driven DTOs for PHP 8.4+ — up to 60× faster hydration and serialization than the most popular alternative, zero reflection at runtime.**
1212
Works standalone or inside Laravel 12–13.
1313

1414
```bash
@@ -31,18 +31,18 @@ composer require std-out/simple-data-objects
3131

3232
### Performance
3333

34-
Benchmarked against **the most popular full-featured data-object library in the PHP/Laravel ecosystem** — identical DTO shapes, 20,000 iterations per scenario, PHP 8.4:
34+
Benchmarked against **the most popular full-featured data-object library in the PHP/Laravel ecosystem** — identical DTO shapes, 20,000 iterations per scenario, PHP 8.4, inside a fully booted Laravel app (not a synthetic standalone script). Medians of 5 runs:
3535

3636
| Scenario | Simple Data Objects | Popular alternative | Advantage |
3737
|---|---|---|---|
38-
| Hydration — flat DTO | ~4,500,000 ops/s | ~130,000 ops/s | **~35× faster** |
39-
| Hydration — nested DTO | ~2,200,000 ops/s | ~74,000 ops/s | **~30× faster** |
40-
| Hydration — collection of 20 | ~270,000 ops/s | ~7,500 ops/s | **~36× faster** |
41-
| Serialization — flat DTO | ~7,400,000 ops/s | ~200,000 ops/s | **~37× faster** |
42-
| Serialization — nested DTO | ~4,000,000 ops/s | ~117,000 ops/s | **~34× faster** |
43-
| Peak memory — streaming 50,000 rows | 0.26 MB with `lazyCollection()` | ~13 MB | **~50× less memory** |
38+
| Hydration — flat DTO | ~6,550,000 ops/s | ~132,000 ops/s | **~50× faster** |
39+
| Hydration — nested DTO | ~3,390,000 ops/s | ~95,000 ops/s | **~36× faster** |
40+
| Hydration — collection of 20 | ~209,000 ops/s | ~10,200 ops/s | **~21× faster** |
41+
| Serialization — flat DTO | ~14,900,000 ops/s | ~249,000 ops/s | **~60× faster** |
42+
| Serialization — nested DTO | ~7,500,000 ops/s | ~166,000 ops/s | **~47× faster** |
43+
| Streaming — 100k-row CSV import | ~67,200 rows/s | ~35,800 rows/s | **~87% faster**, same flat ~12 KB memory footprint |
4444

45-
Absolute numbers vary with hardware; the ratios stay stable across runs. CPU time per operation follows the same ratios — less CPU burned per request means more headroom per server.
45+
Absolute numbers vary with hardware; the ratios stay stable across runs. CPU time per operation follows the same ratios — less CPU burned per request means more headroom per server. Streaming a large import with `lazyCollection()` keeps memory flat regardless of row count — the win there is architectural (no full materialization), not a per-row memory difference from the alternative, which also streams comparably once both sides are measured on equal footing.
4646

4747
Don't take the numbers on faith — **[run the benchmarks yourself](https://github.com/std-out/simple-data-objects-benchmark)**: clone the companion repo, `make bench`, or swap in your own payload shapes.
4848

@@ -147,7 +147,7 @@ Every worker then starts with opcache-compiled metadata **and** hydration/serial
147147

148148
```php
149149
foreach (UserData::lazyCollection($csvRows) as $user) {
150-
$importer->process($user); // 50k rows, ~0.26 MB peak instead of ~13 MB
150+
$importer->process($user); // ~12 KB peak at 100k rows — flat regardless of row count
151151
}
152152
```
153153

0 commit comments

Comments
 (0)