326 lines
8.1 KiB
Markdown
326 lines
8.1 KiB
Markdown
# FlexLöve Performance Profiler
|
|
|
|
A comprehensive profiling system for stress testing and benchmarking FlexLöve's performance with the full Love2D runtime.
|
|
|
|
## Quick Start
|
|
|
|
1. **Run the profiler:**
|
|
```bash
|
|
love profiling/
|
|
```
|
|
|
|
2. **Select a profile** using arrow keys and press ENTER
|
|
|
|
3. **View real-time metrics** in the overlay (FPS, frame time, memory)
|
|
|
|
## Running Specific Profiles
|
|
|
|
Run a specific profile directly from the command line:
|
|
|
|
```bash
|
|
love profiling/ layout_stress_profile
|
|
love profiling/ animation_stress_profile
|
|
love profiling/ render_stress_profile
|
|
love profiling/ event_stress_profile
|
|
love profiling/ immediate_mode_profile
|
|
love profiling/ memory_profile
|
|
```
|
|
|
|
## Available Profiles
|
|
|
|
### Layout Stress Profile
|
|
Tests layout engine performance with large element hierarchies.
|
|
|
|
**Features:**
|
|
- Adjustable element count (100-5000)
|
|
- Multiple nesting levels
|
|
- Flexbox layout stress testing
|
|
- Dynamic element creation
|
|
|
|
**Controls:**
|
|
- `+` / `-` : Increase/decrease element count by 50
|
|
- `R` : Reset to default (100 elements)
|
|
- `ESC` : Return to menu
|
|
|
|
### Animation Stress Profile
|
|
Tests animation system performance with many concurrent animations.
|
|
|
|
**Features:**
|
|
- 100-1000 animated elements
|
|
- Multiple animation properties (position, size, color, opacity)
|
|
- Various easing functions
|
|
- Concurrent animations
|
|
|
|
**Controls:**
|
|
- `+` / `-` : Increase/decrease animation count by 50
|
|
- `SPACE` : Pause/resume all animations
|
|
- `R` : Reset animations
|
|
- `ESC` : Return to menu
|
|
|
|
### Render Stress Profile
|
|
Tests rendering performance with heavy draw operations.
|
|
|
|
**Features:**
|
|
- Thousands of drawable elements
|
|
- Rounded rectangles with various radii
|
|
- Text rendering stress
|
|
- Layering and overdraw scenarios
|
|
- Effects (blur, shadows)
|
|
|
|
**Controls:**
|
|
- `+` / `-` : Increase/decrease element count
|
|
- `1-5` : Toggle different render features
|
|
- `R` : Reset
|
|
- `ESC` : Return to menu
|
|
|
|
### Event Stress Profile
|
|
Tests event handling performance at scale.
|
|
|
|
**Features:**
|
|
- Many interactive elements (500+)
|
|
- Event propagation through deep hierarchies
|
|
- Hover and click event handling
|
|
- Hit testing performance
|
|
- Visual feedback on interactions
|
|
|
|
**Controls:**
|
|
- `+` / `-` : Increase/decrease interactive elements
|
|
- Move mouse to test hover performance
|
|
- Click elements to test event dispatch
|
|
- `R` : Reset
|
|
- `ESC` : Return to menu
|
|
|
|
### Immediate Mode Profile
|
|
Tests immediate mode where UI is recreated every frame.
|
|
|
|
**Features:**
|
|
- Full UI recreation each frame
|
|
- Performance comparison vs retained mode
|
|
- 50-300 element recreation
|
|
- State persistence across frames
|
|
- BeginFrame/EndFrame pattern
|
|
|
|
**Controls:**
|
|
- `+` / `-` : Increase/decrease element count
|
|
- `R` : Reset
|
|
- `ESC` : Return to menu
|
|
|
|
### Memory Profile
|
|
Tests memory usage patterns and garbage collection.
|
|
|
|
**Features:**
|
|
- Memory growth tracking
|
|
- GC frequency and pause time monitoring
|
|
- Element creation/destruction cycles
|
|
- ImageCache memory testing
|
|
- Memory leak detection
|
|
|
|
**Controls:**
|
|
- `SPACE` : Create/destroy element batch
|
|
- `G` : Force garbage collection
|
|
- `R` : Reset memory tracking
|
|
- `ESC` : Return to menu
|
|
|
|
## Performance Metrics
|
|
|
|
The profiler overlay displays:
|
|
|
|
- **FPS** : Current frames per second (color-coded: green=good, yellow=warning, red=critical)
|
|
- **Frame Time** : Current frame time in milliseconds
|
|
- **Avg Frame** : Average frame time across all frames
|
|
- **Min/Max** : Minimum and maximum frame times
|
|
- **P95/P99** : 95th and 99th percentile frame times
|
|
- **Memory** : Current memory usage in MB
|
|
- **Peak Memory** : Maximum memory usage recorded
|
|
- **Top Markers** : Custom timing markers (if used by profile)
|
|
|
|
## Keyboard Shortcuts
|
|
|
|
### Global Controls
|
|
- `ESC` : Return to menu (from profile) or quit (from menu)
|
|
- `R` : Reset current profile
|
|
- `F11` : Toggle fullscreen
|
|
|
|
### Menu Navigation
|
|
- `↑` / `↓` : Navigate profile list
|
|
- `ENTER` / `SPACE` : Select profile
|
|
|
|
## Creating Custom Profiles
|
|
|
|
Create a new file in `profiling/__profiles__/` following this template:
|
|
|
|
```lua
|
|
local FlexLove = require("FlexLove")
|
|
|
|
local profile = {}
|
|
|
|
function profile.init()
|
|
-- Initialize FlexLove and build your UI
|
|
FlexLove.init({
|
|
width = love.graphics.getWidth(),
|
|
height = love.graphics.getHeight(),
|
|
})
|
|
|
|
-- Build your test UI here
|
|
end
|
|
|
|
function profile.update(dt)
|
|
-- Update logic (animations, state changes, etc)
|
|
end
|
|
|
|
function profile.draw()
|
|
-- Draw your UI
|
|
-- The profiler overlay is drawn automatically
|
|
end
|
|
|
|
function profile.keypressed(key)
|
|
-- Handle keyboard input specific to your profile
|
|
end
|
|
|
|
function profile.resize(w, h)
|
|
-- Handle window resize
|
|
FlexLove.resize(w, h)
|
|
end
|
|
|
|
function profile.reset()
|
|
-- Reset profile to initial state
|
|
end
|
|
|
|
function profile.cleanup()
|
|
-- Clean up resources
|
|
end
|
|
|
|
return profile
|
|
```
|
|
|
|
The filename (without `.lua` extension) will be used as the profile name in the menu.
|
|
|
|
## Using PerformanceProfiler Directly
|
|
|
|
For custom timing markers in your profile:
|
|
|
|
```lua
|
|
local PerformanceProfiler = require("profiling.utils.PerformanceProfiler")
|
|
local profiler = PerformanceProfiler.new()
|
|
|
|
function profile.update(dt)
|
|
profiler:beginFrame()
|
|
|
|
-- Mark custom operation
|
|
profiler:markBegin("my_operation")
|
|
-- ... do something expensive ...
|
|
profiler:markEnd("my_operation")
|
|
|
|
profiler:endFrame()
|
|
end
|
|
|
|
function profile.draw()
|
|
-- Draw profiler overlay
|
|
profiler:draw(10, 10)
|
|
|
|
-- Export report
|
|
local report = profiler:getReport()
|
|
print("Average FPS:", report.fps.average)
|
|
print("My operation avg time:", report.markers.my_operation.average)
|
|
end
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Edit `profiling/conf.lua` to adjust:
|
|
- Window size (default: 1280x720)
|
|
- VSync (default: off for uncapped FPS)
|
|
- MSAA (default: 4x)
|
|
- Stencil support (required for rounded rectangles)
|
|
|
|
## Interpreting Results
|
|
|
|
### Good Performance
|
|
- FPS: 60+ (displayed in green)
|
|
- Frame Time: < 13ms
|
|
- P99 Frame Time: < 16.67ms
|
|
|
|
### Warning Signs
|
|
- FPS: 45-60 (displayed in yellow)
|
|
- Frame Time: 13-16.67ms
|
|
- Frequent GC pauses
|
|
|
|
### Critical Issues
|
|
- FPS: < 45 (displayed in red)
|
|
- Frame Time: > 16.67ms
|
|
- Memory continuously growing
|
|
- Stuttering/frame drops
|
|
|
|
## Troubleshooting
|
|
|
|
### Profile fails to load
|
|
- Check Lua syntax errors in the profile file
|
|
- Ensure `profile.init()` function exists
|
|
- Verify FlexLove is initialized properly
|
|
|
|
### Low FPS in all profiles
|
|
- Disable VSync in conf.lua
|
|
- Check GPU drivers are up to date
|
|
- Try reducing element counts
|
|
- Monitor CPU/GPU usage externally
|
|
|
|
### Memory keeps growing
|
|
- Check for element leaks (not cleaning up)
|
|
- Verify event handlers are removed
|
|
- Test with Memory Profile to identify leaks
|
|
- Force GC with `G` key to see if memory is released
|
|
|
|
### Profiler overlay not showing
|
|
- Ensure PerformanceProfiler is initialized in profile
|
|
- Call `profiler:beginFrame()` and `profiler:endFrame()`
|
|
- Check overlay isn't being drawn off-screen
|
|
|
|
## Architecture
|
|
|
|
```
|
|
profiling/
|
|
├── conf.lua # Love2D configuration
|
|
├── main.lua # Main entry point and harness
|
|
├── __profiles__/ # Profile test files
|
|
│ ├── layout_stress_profile.lua
|
|
│ ├── animation_stress_profile.lua
|
|
│ ├── render_stress_profile.lua
|
|
│ ├── event_stress_profile.lua
|
|
│ ├── immediate_mode_profile.lua
|
|
│ └── memory_profile.lua
|
|
└── utils/
|
|
└── PerformanceProfiler.lua # Profiling utility module
|
|
```
|
|
|
|
## Tips for Profiling
|
|
|
|
1. **Start small**: Begin with low element counts and scale up
|
|
2. **Watch for drop-offs**: Note when FPS drops below 60
|
|
3. **Compare modes**: Test both immediate and retained modes
|
|
4. **Long runs**: Run profiles for 5+ minutes to catch memory leaks
|
|
5. **Use markers**: Add custom markers for specific operations
|
|
6. **Export data**: Use `profiler:exportJSON()` for detailed analysis
|
|
7. **Monitor externally**: Use OS tools to monitor CPU/GPU usage
|
|
|
|
## Performance Targets
|
|
|
|
FlexLöve should maintain 60 FPS with:
|
|
- 1000+ simple elements (retained mode)
|
|
- 200+ elements (immediate mode)
|
|
- 500+ concurrent animations
|
|
- 1000+ draw calls
|
|
- 500+ interactive elements
|
|
|
|
## Contributing
|
|
|
|
To add a new profile:
|
|
|
|
1. Create a new file in `__profiles__/` with `_profile.lua` suffix
|
|
2. Follow the profile template structure
|
|
3. Test thoroughly with various configurations
|
|
4. Document controls and features in this README
|
|
|
|
## License
|
|
|
|
Same license as FlexLöve (MIT)
|