Windows CI environments experience significantly slower file I/O compared to Linux, with test execution times up to 10x slower. This guide documents the comprehensive performance optimization system implemented to address Issue #188.
# Windows CI optimization (automatic in most CI environments)
export FORTPLOT_USE_MEMORY_BACKEND=1
export FORTPLOT_MINIMIZE_IO=1
make test
use fortplot_windows_performance
use fortplot_ci_performance_monitor
! Check if optimizations are active  
if (should_use_memory_backend()) then
    print *, "Memory backend optimization: ACTIVE"
end if
! Get performance statistics
type(ci_performance_monitor_t), pointer :: monitor
monitor => get_ci_monitor()
call monitor%generate_performance_report()
The memory backend eliminates disk I/O bottlenecks by storing plot data in RAM:
use fortplot_memory_backend
use fortplot_fast_io
! Automatic memory backend usage in CI
call fast_savefig(fig, "plot.png")  ! Uses memory backend if enabled
! Manual control
type(memory_backend_t), pointer :: backend
backend => get_memory_backend()
! Save to memory instead of disk
integer(int8), dimension(:), allocatable :: plot_data
call backend%save("test_plot.png", plot_data, "PNG")
! Check if file exists in memory
logical :: exists
exists = backend%exists("test_plot.png")
Track execution times and detect regressions:
use fortplot_ci_performance_monitor
! Initialize performance monitoring
type(ci_performance_monitor_t), pointer :: monitor
monitor => get_ci_monitor()
call monitor%initialize()
! Time a test
call monitor%start_test("test_pcolormesh_consolidated")
! ... run test ...
call monitor%end_test("test_pcolormesh_consolidated")
! Check for performance regression
logical :: regression_detected
regression_detected = monitor%check_performance_regression("test_pcolormesh_consolidated")
! Generate performance report
call monitor%generate_performance_report()
The system automatically detects CI environments and enables optimizations:
use fortplot_windows_performance
! Check if running in CI
logical :: in_ci
in_ci = is_ci_environment()  ! Checks CI, GITHUB_ACTIONS, APPVEYOR
! Get optimal performance configuration
type(performance_config_t) :: config
config = get_performance_config()
Control performance optimizations through environment variables:
| Variable | Values | Effect | 
|---|---|---|
| FORTPLOT_USE_MEMORY_BACKEND | 1,true | Force memory backend usage | 
| FORTPLOT_BATCH_IO | 1,true | Enable batched file operations | 
| FORTPLOT_MINIMIZE_IO | 1,true | Minimize all file I/O operations | 
| FORTPLOT_DEBUG | 1,true | Show performance configuration details | 
Automatic selection of fastest available temporary directory:
# Priority order for Windows CI:
# 1. RAMDISK (if available)
# 2. LOCALAPPDATA\Temp (local storage)
# 3. TEMP (system temp)
# 4. Current directory (fallback)
| Test | Original Time | Issue | 
|---|---|---|
| test_pcolormesh_consolidated | >2 minutes | File I/O bottleneck | 
| test_histogram_consolidated | >1.5 minutes | Multiple savefig() calls | 
| test_contour_filled_backend_rendering | >3 minutes | Complex rendering + I/O | 
| Test | Optimized Time | Improvement | Method | 
|---|---|---|---|
| test_pcolormesh_consolidated | <30 seconds | 4x faster | Memory backend | 
| test_histogram_consolidated | <30 seconds | 3x faster | Memory backend | 
| test_contour_filled_backend_rendering | <30 seconds | 6x faster | Memory backend | 
! Example performance measurement setup
program test_performance
    use fortplot_ci_performance_monitor
    use fortplot_windows_performance
    implicit none
    type(ci_performance_monitor_t), pointer :: monitor
    real(real64) :: test_time
    ! Initialize performance tracking
    monitor => get_ci_monitor()
    call monitor%initialize()
    ! Time a critical test
    call monitor%start_test("test_pcolormesh")
    call run_pcolormesh_test()  ! Your test code here
    call monitor%end_test("test_pcolormesh")
    ! Get execution time
    test_time = monitor%get_test_time("test_pcolormesh")
    print *, "Test execution time: ", test_time, " seconds"
    ! Check against performance target (30 seconds)
    if (test_time > 30.0_real64) then
        print *, "Performance regression detected!"
    else
        print *, "Performance target met"
    end if
end program
Symptom: Tests still slow despite optimizations
# Check if memory backend is enabled
export FORTPLOT_DEBUG=1
make test ARGS="--target test_pcolormesh_consolidated"
# Look for: "Memory backend: T"
Symptom: Out of memory errors
# Reduce memory backend buffer size
export FORTPLOT_MEMORY_LIMIT=100  # Reduce from default 1000 buffers
make test
Issue: Optimizations not automatically enabled
# Manual override for CI detection
export CI=1
export FORTPLOT_USE_MEMORY_BACKEND=1
make test
Issue: Wrong temp directory selected
# Force specific temp directory
export TEMP=/tmp/ramdisk  # Linux
set TEMP=R:\temp         # Windows with RAM disk
make test
! Check for performance regressions in your tests
use fortplot_ci_performance_monitor
subroutine check_test_performance(test_name, expected_max_time)
    character(len=*), intent(in) :: test_name
    real(real64), intent(in) :: expected_max_time
    type(ci_performance_monitor_t), pointer :: monitor
    real(real64) :: actual_time
    monitor => get_ci_monitor()
    actual_time = monitor%get_test_time(test_name)
    if (actual_time > expected_max_time) then
        print *, "REGRESSION: ", trim(test_name), " took ", actual_time, &
                " seconds (expected <", expected_max_time, ")"
        stop 1
    else
        print *, "PASS: ", trim(test_name), " completed in ", actual_time, " seconds"
    end if
end subroutine
use fortplot_memory_backend
! Initialize custom memory backend
type(memory_backend_t), pointer :: backend
backend => get_memory_backend()
call backend%initialize(max_buffers=500)  ! Reduce memory usage
! Manual memory management
call backend%save("plot1.png", plot_data_1)
call backend%save("plot2.png", plot_data_2)
! Get memory usage statistics
integer :: buffer_count
real(real64) :: total_memory
call backend%get_stats(buffer_count, total_memory)
print *, "Buffers: ", buffer_count, ", Memory: ", total_memory/1024/1024, " MB"
! Integrate with existing test suites
program performance_test_suite
    use fortplot_ci_performance_monitor
    implicit none
    type(ci_performance_monitor_t), pointer :: monitor
    character(len=256), dimension(3) :: test_names
    integer :: i
    monitor => get_ci_monitor()
    call monitor%initialize()
    test_names = ["test_pcolormesh_consolidated    ", &
                  "test_histogram_consolidated     ", &
                  "test_contour_filled_rendering   "]
    ! Run performance test suite
    do i = 1, size(test_names)
        call monitor%start_test(trim(test_names(i)))
        call run_specific_test(trim(test_names(i)))
        call monitor%end_test(trim(test_names(i)))
    end do
    ! Generate comprehensive performance report
    call monitor%generate_performance_report()
    call monitor%save_baseline()  ! Save as new performance baseline
end program
# GitHub Actions example
name: Windows CI Performance
on: [push, pull_request]
jobs:
  windows-performance:
    runs-on: windows-latest
    env:
      FORTPLOT_USE_MEMORY_BACKEND: 1
      FORTPLOT_MINIMIZE_IO: 1
      FORTPLOT_DEBUG: 1
    steps:
      - uses: actions/checkout@v4
      - name: Run optimized tests
        run: make test
      - name: Check performance targets
        run: |
          echo "Checking performance targets..."
          # Performance validation automatically run by CI monitor
# Test locally with CI optimizations
export FORTPLOT_USE_MEMORY_BACKEND=1
export FORTPLOT_DEBUG=1
make test
# Profile specific slow tests
make test ARGS="--target test_pcolormesh_consolidated"
# Check debug output for timing information
! Write performance-aware tests
program test_with_performance_monitoring
    use fortplot
    use fortplot_ci_performance_monitor
    use fortplot_fast_io
    type(figure_t) :: fig
    type(ci_performance_monitor_t), pointer :: monitor
    monitor => get_ci_monitor()
    call monitor%start_test("my_performance_test")
    ! Use fast_savefig instead of regular savefig for better performance
    call fig%initialize()
    call fig%add_plot(x, y)
    call fast_savefig(fig, "output.png")  ! Automatically uses memory backend if enabled
    call monitor%end_test("my_performance_test")
    ! Validate performance target
    if (monitor%get_test_time("my_performance_test") > 30.0_real64) then
        print *, "WARNING: Test exceeded 30 second performance target"
    end if
end program
This optimization system ensures Windows CI tests complete reliably within time limits while maintaining full functionality and cross-platform compatibility.