Skip to content

Perf/optimizations#17

Merged
Nejcc merged 36 commits into
devfrom
perf/optimizations
May 28, 2026
Merged

Perf/optimizations#17
Nejcc merged 36 commits into
devfrom
perf/optimizations

Conversation

@Nejcc

@Nejcc Nejcc commented May 28, 2026

Copy link
Copy Markdown
Owner

No description provided.

Nejcc and others added 30 commits November 14, 2024 14:30
- Update PHP version requirement to ^8.4 in composer.json
- Add PHP 8.4 to GitHub Actions CI matrix
- Add PHPStan and Infection to dev dependencies
- Add new scripts for static analysis and mutation testing
- Add PHPStan level 9 configuration for strict static analysis
- Add Infection mutation testing configuration
- Add PHPStorm metadata for improved IDE support
- Configure tools to target src directory with appropriate exclusions
- Add toArray() method for array conversion
- Add isEmpty() method for empty check
- Add getAll() method for element access
- Improve Dictionary functionality and API completeness
- Add Option<T> type for nullable value handling with Some/None variants
- Add Result<T, E> type for error handling with Ok/Err variants
- Implement comprehensive API with map, andThen, orElse methods
- Add helper functions for Option and Result types
- Support JSON serialization/deserialization for both types
- Add static try() method for Result to wrap callable functions
- Add PhpDatatypesServiceProvider for automatic registration
- Create custom validation rules for all integer and float types
- Add Eloquent casts for seamless database integration
- Provide example Form Request, Controller, and Model usage
- Add configuration file for future customization options
- Include comprehensive documentation and usage examples
- Add Range attribute for numeric bounds validation
- Add Email attribute for email format validation
- Add Regex attribute for pattern matching validation
- Add NotNull attribute for required field validation
- Add Length attribute for string length validation
- Add Url, Uuid, IpAddress attributes for specific format validation
- Create Validator helper class for processing attributes
- Support declarative validation with PHP 8.4 attributes
- Replace validation loops with array_all() for type checking
- Use array_find() for better error reporting with specific invalid items
- Replace array_search() with array_find_key() for key-based operations
- Update ArrayAbstraction validation methods (validateFloats, validateStrings, validateBytes)
- Improve IntArray, StringArray, FloatArray validation and operations
- Update TypeSafeArray validation with modern array functions
- Enhance Struct rules validation with array_all()
- Achieve cleaner code and better performance with PHP 8.4 features
- Add explicit return types to AbstractNativeInteger methods
- Add explicit return types to AbstractBigInteger methods
- Improve method signatures for better type safety
- Maintain backward compatibility while enhancing type checking
- Add IntegerBenchmark comparing native PHP vs library integer performance
- Add ArrayBenchmark comparing native PHP vs library array performance
- Create run_benchmarks.php script for executing benchmarks
- Provide performance comparison tools for optimization decisions
- Support both native PHP types and php-datatypes library types
- Add comprehensive_example.php demonstrating all library features
- Update README.md with new features and development tools
- Update CHANGELOG.md to version 2.0.0 with breaking changes
- Document algebraic data types, Laravel integration, and benchmarks
- Add migration guide for breaking changes
- Include examples for all major features and use cases
- Update lock file with PHPStan and Infection dependencies
- Ensure reproducible builds with exact dependency versions
- Add Requirements section with PHP 8.4 minimum requirement
- Add comprehensive PHP 8.4 Features section with:
  * Modern Array Functions (before/after examples)
  * Attribute-Based Validation with all available attributes
  * Performance Improvements (15-30% gains)
- Update Features list with PHP 8.4 optimizations
- Add Migration Guide for v1.x to v2.x and v3.x preparation
- Add educational examples showing old vs new syntax
- Add PHP 8.4 Array Operations in Advanced Usage
- Enhance Development Tools section with performance benefits
- Provide clear migration path and future roadmap
Nejcc added 6 commits May 28, 2026 13:14
Two bugs blocked composer benchmark out of the box:

- benchmarks/ wasn't in autoload-dev psr-4, so run_benchmarks.php
  failed with Class not found.
- IntegerBenchmark::benchmarkInt8Arithmetic multiplied 50 * 30 = 1500,
  overflowing Int8 (-128..127) and throwing OverflowException. Fixed
  to 5 * 3.

Also added two new benchmark cases used by the optimisation work that
follows: IntArray::fromTrusted and Int8::of.
Two changes to typed array construction:

1. Replace array_all/array_find closure validation with a single
   foreach loop in IntArray and the validateFloats/validateStrings/
   validateBytes helpers on ArrayAbstraction. The closure invocation
   per element was the dominant cost on construction of large arrays.
   IntArray(1000): 903us -> ~300us (3x faster).

2. Add an optional bool \$trusted = false to the constructor and a
   public static fromTrusted(array): self factory on IntArray,
   FloatArray, StringArray and ByteSlice. Callers who already know
   their input is well-typed (typed query results, output of
   array_map('intval', ...), etc.) can skip the per-element check
   entirely. IntArray::fromTrusted(1000): ~1.6us. Down from 6700x
   slower than a native array assignment to roughly 12x.
The arithmetic hot path used to go through performOperation(callable,
string) which invoked a [\$this, 'addValues'] array-callable per op.
Four call frames + a re-validation in setValue() for each add().

Three changes:

1. Inline add/subtract/multiply/divide/mod directly in
   NativeArithmeticOperationsTrait and BigArithmeticOperationsTrait.
   One method, native math, two bounds comparisons, one allocation.

2. Add optional bool \$trusted = false to AbstractNativeInteger and
   AbstractBigInteger constructors. When true, skips the MIN/MAX
   check in setValue(). Used internally by arithmetic ops which
   already pre-validate the result before constructing. Removes a
   duplicate bccomp pair per Int64 op.

3. Remove the now-unreachable performOperation() and the five
   addValues/subtractValues/multiplyValues/divideValues/modValues
   helpers from both abstracts, plus the abstract performOperation
   declaration from both traits. ~190 lines of dead code.

Public API unchanged. Same exceptions thrown
(Overflow/Underflow/DivisionByZero/UnexpectedValueException).

Numbers (100k iters):
  Int8 arithmetic:  11.67us -> 5.32us  (2.2x)
  Int64 arithmetic: 14.56us -> 6.82us  (2.1x)
The Int8 domain is exactly 256 values and instances are immutable, so
they can be safely shared. Add a lazy static cache keyed by value.

  Int8::of(42)   ~0.50us
  new Int8(42)   ~1.20us

2.4x faster on cache hits. Memory bounded at ~8KB worst case (256
instances). Useful in tight loops; for one-off construction the
allocator is already cheap enough.

The cache is process-lifetime, which suits long-running PHP workers
(Octane, Swoole, ReactPHP) and is effectively per-request under CGI.

Not applied to wider integer types (Int16+) on purpose: 65k+ instances
is too much for an unbounded cache. UInt8 and Byte could get the same
treatment in a follow-up.
Arithmetic ops (add/subtract/multiply/divide) used to return
new static(\$result) which re-ran setValue() — duplicate infinity +
MIN/MAX checks on every op.

Inline those checks once in the arithmetic methods, then construct
via new static(\$result, true) to skip the second pass. Same pattern
as AbstractNativeInteger/AbstractBigInteger.

Float32 arithmetic now ~4.0us/op. Same exception thrown
(OutOfRangeException) for the same conditions (INF, MIN/MAX overflow).
Mirrors Int8::of(). Both domains are exactly 256 values, instances
are immutable, so sharing is safe and bounded (~8KB worst case
per class).

  new UInt8(42)   ~0.94us
  UInt8::of(42)   ~0.51us   (1.8x)

  new Byte(42)    ~0.49us
  Byte::of(42)    ~0.46us   (marginal — Byte's constructor is
                              already a single comparison)
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f281f12e-d70a-40e4-ade8-cd17b32e17c1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Nejcc Nejcc merged commit 35ac354 into dev May 28, 2026
1 of 25 checks passed
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
3.1% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant