Files
FlexLove/profiling/README.md
2025-11-20 09:30:01 -05:00

8.1 KiB

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:

    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:

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:

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:

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)