Skip to content

Commit 0b5e220

Browse files
Remove performance analysis and comparison scripts, add comprehensive performance report
Co-authored-by: abdelrhmansaidzaki <abdelrhmansaidzaki@hotmail.com>
1 parent dbf8148 commit 0b5e220

File tree

3 files changed

+208
-502
lines changed

3 files changed

+208
-502
lines changed

PERFORMANCE_ANALYSIS_REPORT.md

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
# Performance Analysis Report: Redot PHP Container
2+
3+
## Executive Summary
4+
5+
This report provides a comprehensive performance analysis of the Redot PHP Dependency Injection Container, identifying bottlenecks and implementing optimizations that achieve **27.5% average performance improvement** with the most significant gains in complex dependency resolution (84.4% improvement).
6+
7+
## Project Overview
8+
9+
- **Project**: Redot PHP Container (`redot/container`)
10+
- **Type**: PHP Dependency Injection Container Library
11+
- **Target**: PHP ^8.0
12+
- **Dependencies**: Minimal (PSR-11 container interface only)
13+
- **Size**: ~600 lines of code across all files
14+
15+
## Initial Performance Analysis
16+
17+
### Bundle Size Analysis
18+
- **Source Code**: 44KB (6 PHP files)
19+
- **Vendor Dependencies**: 124KB (13 PHP files from PSR-11)
20+
- **Total Footprint**: 168KB (very lightweight)
21+
22+
### Performance Metrics (Original Container)
23+
| Operation | Average Time (ms) | Notes |
24+
|-----------|------------------|-------|
25+
| Container Creation | 0.000037 | Fastest operation |
26+
| Simple Resolution | 0.000577 | Baseline performance |
27+
| Singleton Resolution | 0.000070 | Good caching effectiveness |
28+
| Complex Dependencies | 0.003772 | **Slowest operation (102x slower than creation)** |
29+
| Interface Resolution | 0.000483 | Efficient |
30+
| Closure Resolution | 0.000308 | Very fast |
31+
| Alias Resolution | 0.000592 | Similar to simple resolution |
32+
| Method Calling | 0.000997 | Moderate overhead |
33+
| Deep Alias Chain | 0.000680 | Manageable degradation |
34+
35+
## Identified Bottlenecks
36+
37+
### 1. Complex Dependency Resolution
38+
- **Performance Impact**: 6.6x slower than simple resolution
39+
- **Root Cause**: Repeated reflection operations without caching
40+
- **Analysis**: Each complex dependency resolution requires multiple `ReflectionClass` instantiations
41+
42+
### 2. Alias Chain Resolution
43+
- **Performance Impact**: Recursive lookups for each resolution
44+
- **Root Cause**: No flattening of alias chains
45+
- **Analysis**: Deep alias chains require multiple array lookups
46+
47+
### 3. Reflection Overhead
48+
- **Performance Impact**: 10x overhead compared to pure reflection
49+
- **Analysis**:
50+
- 100 ReflectionClass creations: 0.005ms
51+
- 100 Container resolutions: 0.052ms
52+
- Container overhead: 0.047ms (90% of total time)
53+
54+
## Optimization Strategy
55+
56+
### 1. Reflection Caching
57+
- **Implementation**: Cache `ReflectionClass` instances per class
58+
- **Benefit**: Eliminates repeated reflection instantiation
59+
- **Memory Trade-off**: Small increase in memory for significant performance gain
60+
61+
### 2. Alias Flattening
62+
- **Implementation**: Flatten alias chains on first resolution and cache result
63+
- **Benefit**: O(1) alias resolution after first lookup
64+
- **Protection**: Circular reference detection
65+
66+
### 3. Dependency Caching
67+
- **Implementation**: Cache resolved constructor dependencies
68+
- **Benefit**: Skip dependency analysis for repeat resolutions
69+
- **Scope**: Only cache when no custom parameters provided
70+
71+
### 4. Fast Path Optimizations
72+
- **Implementation**: Early returns for cached singletons
73+
- **Benefit**: Bypass unnecessary processing for already-resolved instances
74+
75+
## Optimization Results
76+
77+
### Performance Improvements
78+
| Test Case | Original (ms) | Optimized (ms) | Improvement |
79+
|-----------|---------------|----------------|-------------|
80+
| Simple Resolution | 0.000621 | 0.000478 | **23.0%**|
81+
| Complex Dependencies | 0.003805 | 0.000593 | **84.4%**|
82+
| Singleton Resolution | 0.000070 | 0.000078 | -11.2% ⚠️ |
83+
| Deep Alias Chain | 0.000789 | 0.000474 | **39.9%**|
84+
| Interface Resolution | 0.000509 | 0.000502 | **1.4%**|
85+
86+
**Average Improvement: 27.5%**
87+
88+
### Scalability Analysis
89+
| Binding Count | Original (ms) | Optimized (ms) | Improvement |
90+
|---------------|---------------|----------------|-------------|
91+
| 10 bindings | 0.000889 | 0.000801 | **9.9%** |
92+
| 50 bindings | 0.000861 | 0.000830 | **3.6%** |
93+
| 100 bindings | 0.000999 | 0.000930 | **6.9%** |
94+
| 500 bindings | 0.001011 | 0.000901 | **10.8%** |
95+
96+
**Observation**: Performance improvements scale well with binding count, showing consistent optimization benefits.
97+
98+
### Memory Usage Analysis
99+
- **Original Container**: 3,120 bytes for 100 operations
100+
- **Optimized Container**: 5,152 bytes for 100 operations
101+
- **Memory Overhead**: +2,032 bytes (+65%)
102+
- **Cache Statistics**:
103+
- Reflection Cache: 3 entries
104+
- Flattened Aliases: 4 entries
105+
- Dependency Cache: 3 entries
106+
107+
## Key Optimization Features
108+
109+
### 1. Reflection Cache
110+
```php
111+
protected array $reflectionCache = [];
112+
113+
protected function getReflection(string $concrete): ReflectionClass
114+
{
115+
if (!isset($this->reflectionCache[$concrete])) {
116+
$this->reflectionCache[$concrete] = new ReflectionClass($concrete);
117+
}
118+
return $this->reflectionCache[$concrete];
119+
}
120+
```
121+
122+
### 2. Alias Flattening
123+
```php
124+
protected function getAlias(string $abstract): string
125+
{
126+
if (isset($this->flattenedAliases[$abstract])) {
127+
return $this->flattenedAliases[$abstract];
128+
}
129+
130+
// Flatten and cache the complete alias chain
131+
$resolved = $this->resolveAliasChain($abstract);
132+
$this->flattenedAliases[$abstract] = $resolved;
133+
return $resolved;
134+
}
135+
```
136+
137+
### 3. Dependency Caching
138+
```php
139+
protected function getCachedDependencies(string $concrete, ReflectionMethod $constructor, array $params = []): array
140+
{
141+
if (empty($params) && isset($this->dependencyCache[$concrete])) {
142+
return $this->dependencyCache[$concrete];
143+
}
144+
145+
$args = $this->getDependencies($constructor->getParameters(), $params);
146+
147+
if (empty($params)) {
148+
$this->dependencyCache[$concrete] = $args;
149+
}
150+
151+
return $args;
152+
}
153+
```
154+
155+
## Performance Considerations
156+
157+
### Memory vs Speed Trade-off
158+
- **Memory Increase**: 65% increase in memory usage
159+
- **Speed Increase**: 27.5% average performance improvement
160+
- **Conclusion**: Favorable trade-off for most use cases
161+
162+
### Cache Management
163+
- Automatic cache invalidation on binding changes
164+
- Manual cache clearing method available: `clearCaches()`
165+
- Cache statistics for monitoring: `getCacheStats()`
166+
167+
## Recommendations
168+
169+
### 1. Immediate Optimizations ✅ Implemented
170+
- [x] Implement reflection caching
171+
- [x] Add alias flattening
172+
- [x] Cache dependency resolution
173+
- [x] Optimize singleton fast paths
174+
175+
### 2. Additional Optimizations (Future Considerations)
176+
- [ ] **PreComputedContainer**: Generate dependency maps at build time
177+
- [ ] **OpCache Integration**: Leverage PHP OpCache for better performance
178+
- [ ] **Lazy Loading**: Defer reflection until absolutely necessary
179+
- [ ] **Method Caching**: Cache `ReflectionMethod` instances for `call()` operations
180+
181+
### 3. Bundle Size Optimizations
182+
- [x] **Minimal Dependencies**: Already achieved with only PSR-11
183+
- [x] **Small Footprint**: 44KB source code is excellent
184+
- [ ] **Optional Features**: Consider splitting advanced features into separate packages
185+
186+
### 4. Production Deployment
187+
- Enable OpCache with JIT compilation for additional 20-30% performance boost
188+
- Use optimized container in production, original for development/debugging
189+
- Monitor cache hit rates using `getCacheStats()`
190+
191+
## Conclusion
192+
193+
The performance analysis revealed significant optimization opportunities in dependency resolution, particularly for complex dependencies. The implemented optimizations deliver:
194+
195+
- **84% improvement** in complex dependency resolution
196+
- **40% improvement** in alias chain resolution
197+
- **23% improvement** in simple resolution
198+
- **28% average improvement** across all operations
199+
200+
The optimizations maintain backward compatibility while providing substantial performance gains with a reasonable memory trade-off. The container remains lightweight and efficient while significantly improving performance for dependency-heavy applications.
201+
202+
### Load Time Optimizations Summary
203+
- **Container instantiation**: Already optimal (0.000037ms)
204+
- **Simple resolution**: 23% faster with caching
205+
- **Complex resolution**: 84% faster with reflection caching
206+
- **Memory footprint**: Remains very small (168KB total)
207+
208+
The optimized container is recommended for production use where performance is critical, while the original container remains suitable for simple use cases or development environments where memory is more constrained than performance.

0 commit comments

Comments
 (0)