Optimize code across 5 areas with PHPBench benchmarks#1277
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1277 +/- ##
==========================================
+ Coverage 48.77% 48.99% +0.22%
==========================================
Files 61 61
Lines 2901 2892 -9
==========================================
+ Hits 1415 1417 +2
+ Misses 1486 1475 -11 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
5ca932e to
9f18102
Compare
PHPBench Benchmark ReportEnvironment: PHP 8.4.18, xdebug off, opcache off Optimization Benchmarks (Before vs After)Cycle 1 — GroupActionCollection
Cycle 2 — ArrayDataSource
Cycle 3 — ArraysHelper::testEmpty()
Cycle 4 — Row::getValue() dispatch
Cycle 5 — DateTimeHelper::fromString()
Additional Performance Profiling BenchmarksDataModel — Full Pipeline (ArrayDataSource)
Column Rendering
Property Access Comparison (200 accesses)
Filter Application (2000 rows)
CSV Export Pipeline (2000 rows)
Key Findings
Running Benchmarksmake bench # Run all benchmarks
make bench-baseline # Tag a baseline
make bench-compare # Compare against baselineGenerated by Claude Code |
Cycle 1 - GroupActionCollection: Replace redundant count() ID generation with auto-increment counter; merge 3 foreach loops into 2 in addToFormContainer() (buttons + options in one pass, sub-actions separate). Cycle 2 - ArrayDataSource: Simplify sort flatten with array_merge(...) spread operator; deduplicate DateTime conversion in applyFilterDateRange() to convert row value once before from/to checks. Cycle 3 - ArraysHelper: Simplify testEmpty() by replacing truthy check + in_array([0,'0',false]) with single !== null && !== '' condition. Cycle 4 - Row: Cache type-dispatching closure in constructor via match() to avoid repeated instanceof chain on every getValue() call. Cycle 5 - DateTimeHelper: Extract default formats as class constant to avoid array recreation on every fromString() call. Datagrid::getColumns() uses array_filter+array_keys instead of manual loop for defaultHide. Added PHPBench infrastructure with 5 benchmark classes covering all optimized areas, Makefile targets (bench, bench-baseline, bench-compare). All 29 tests pass, PHPStan level 8 clean, code style clean. https://claude.ai/code/session_014wj5NNHPqbkW4LnnyXX2sB
New benchmarks covering broader performance areas: - DataModelBench: filter, sort, paginate, full pipeline on ArrayDataSource - ColumnRenderBench: element cache, HTML creation/cloning, column types, callback/replacement/plain rendering paths - PropertyAccessBench: singleton accessor, Symfony PropertyAccessor depths, explode overhead, array vs object vs accessor comparison - FilterApplicationBench: text/select/range/multiselect filters, word splitting, conjunction search, multiple filters in sequence - CsvExportBench: strip_tags, value extraction, summary aggregation, fputcsv serialization, full CSV pipeline Total: 10 benchmark classes, ~130 variants across all data sizes. https://claude.ai/code/session_014wj5NNHPqbkW4LnnyXX2sB
9f18102 to
c5c98d1
Compare
Summary
5-cycle code optimization with PHPBench benchmarks to measure improvements. All changes are backward-compatible refactors verified by existing tests (29 pass), PHPStan level 8 (0 errors), and code style (0 violations).
Cycle 1 — GroupActionCollection
count()ID generation with auto-increment counter (~14% faster at 50 actions)addToFormContainer()(~9% faster at 50 actions)Cycle 2 — ArrayDataSource
array_merge(...)spread operator (3.6x faster at 1000 rows: 13.3μs → 3.7μs)applyFilterDateRange()— convert row value once before from/to checks (~47% faster at 1000 rows: 1.37ms → 0.72ms)Cycle 3 — ArraysHelper
testEmpty()by replacing truthy check +in_array([0,'0',false])with single!== null && !== ''condition (~30% faster on large arrays: 3.8μs → 2.6μs)Cycle 4 — Row
match()to avoid repeatedinstanceofchain on everygetValue()call (eliminates 5 unnecessary type checks per column access for common array/Doctrine items)Cycle 5 — DateTimeHelper & Datagrid
fromString()callDatagrid::getColumns()usesarray_filter+array_keysinstead of manual loop for defaultHide columnsPHPBench Infrastructure
phpbench/phpbenchas dev dependencyphpbench.jsonconfigbenchmarks/covering all optimized areasmake bench,make bench-baseline,make bench-compareTest plan
make tests)make phpstan)make cs)make bench)https://claude.ai/code/session_014wj5NNHPqbkW4LnnyXX2sB