Skip to main content

Benchmark System

The Benchmark System provides performance analysis and timing metrics for the Dynamic Dungeon generation pipeline. It allows you to measure generation times, identify bottlenecks, and optimise your procedural generation graphs.

The Benchmark Window

Access the window via: Window > Dynamic Dungeon > Benchmark.

Key Features

1. Generation Timing

The benchmark system tracks the execution time of each node in your generation graph:

  • Per-Node Timing: See how long each individual node takes to execute
  • Job System Metrics: Monitor Unity Job System scheduling and completion times
  • Memory Allocation: Track memory usage during generation

2. Performance Profiling

  • Hotspot Detection: Identify which nodes consume the most processing time
  • Burst Compiler Analysis: Verify that your jobs are being compiled with Burst
  • Parallel Execution: Monitor job dependency chains and parallelisation efficiency

3. Comparative Analysis

  • Before/After Comparison: Compare performance before and after optimisations
  • Graph Comparison: Benchmark different generation configurations side-by-side
  • Historical Data: Track performance trends across multiple generation runs

Using the Benchmark System

Running a Benchmark

  1. Open the Benchmark window
  2. Select your target TilemapWorldGenerator or ConstraintGenerator
  3. Configure benchmark settings:
    • Number of Runs: Execute multiple generations for statistical accuracy
    • Warm-up Runs: Exclude initial runs from results to account for JIT compilation
    • Output Format: Choose between console logs, CSV export, or in-memory analysis
  4. Click Run Benchmark

Interpreting Results

The benchmark results display:

  • Total Generation Time: Overall time from start to finish
  • Node Breakdown: Individual timing for each node in the graph
  • Job Statistics: Number of jobs scheduled, average job duration, and parallelisation factor
  • Memory Usage: Peak memory allocation during generation
tip

Focus optimisation efforts on nodes with the highest individual timing or those that appear frequently in your critical path.


Optimisation Guidelines

Common Bottlenecks

  1. Non-Burst Compiled Jobs: Ensure all job structs have the [BurstCompile] attribute
  2. Excessive Memory Allocation: Reuse NativeArrays/NativeLists where possible
  3. Serial Dependencies: Reduce job dependencies to enable better parallelisation
  4. Large Data Transfers: Minimise data copying between jobs

Best Practices

  • Use [BurstCompile(FloatPrecision.Standard, FloatMode.Fast)] for performance-critical jobs
  • Pre-allocate NativeArrays with known sizes to avoid runtime resizing
  • Batch operations where possible to reduce job scheduling overhead
  • Profile with realistic map sizes that match your target use case

Exporting Benchmark Data

Benchmark results can be exported for further analysis:

  • CSV Format: Export to spreadsheet applications for trend analysis
  • JSON Format: Integrate with automated testing pipelines
  • In-Memory: Access results programmatically via the BenchmarkService API
BenchmarkService service = new BenchmarkService();
BenchmarkResult result = await service.RunBenchmarkAsync(myGenerator, options);

Debug.Log($"Average generation time: {result.AverageTimeMs}ms");
Debug.Log($"Slowest node: {result.SlowestNode.Name} ({result.SlowestNode.TimeMs}ms)");