Module: Ace::TestSupport::PerformanceHelpers

Defined in:
lib/ace/test_support/performance_helpers.rb

Overview

Performance testing helpers for ACE gems

Provides utilities for:

  • Performance assertions (max duration checks)

  • Benchmarking helpers

  • Performance regression detection

Usage:

include Ace::TestSupport::PerformanceHelpers

def test_performance
  assert_performance(0.1) do
    # Code that should complete in < 0.1 seconds
  end
end

Defined Under Namespace

Classes: PerformanceComparison

Instance Method Summary collapse

Instance Method Details

#assert_no_performance_regression(baseline_duration, tolerance: 1.5, message: nil) { ... } ⇒ Object

Assert that performance hasn’t regressed beyond tolerance

Examples:

# Baseline is 0.1s, allow up to 0.15s (1.5x)
assert_no_performance_regression(0.1, tolerance: 1.5) do
  search_operation
end

Parameters:

  • baseline_duration (Float)

    Expected baseline duration in seconds

  • tolerance (Float) (defaults to: 1.5)

    Acceptable tolerance factor (default: 1.5)

  • message (String) (defaults to: nil)

    Optional custom failure message

Yields:

  • Block to measure

Raises:

  • (ArgumentError)


125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/ace/test_support/performance_helpers.rb', line 125

def assert_no_performance_regression(baseline_duration, tolerance: 1.5, message: nil)
  raise ArgumentError, "Block required for regression assertion" unless block_given?

  actual = benchmark_block { yield }[:real]
  max_allowed = baseline_duration * tolerance

  message ||= "Performance regression detected: expected ≤ #{format("%.3f", max_allowed)}s " \
              "(baseline #{format("%.3f", baseline_duration)}s × #{tolerance}), " \
              "but took #{format("%.3f", actual)}s (#{format("%.1f", actual / baseline_duration)}x baseline)"

  assert actual <= max_allowed, message
end

#assert_performance(max_duration, message = nil) { ... } ⇒ Float

Assert that a block completes within the specified duration

Examples:

assert_performance(0.5, "Search should complete quickly") do
  MySearch.new.execute("pattern")
end

Parameters:

  • max_duration (Float)

    Maximum allowed duration in seconds

  • message (String) (defaults to: nil)

    Optional custom failure message

Yields:

  • Block to measure

Returns:

  • (Float)

    Actual duration

Raises:

  • (ArgumentError)


34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/ace/test_support/performance_helpers.rb', line 34

def assert_performance(max_duration, message = nil)
  raise ArgumentError, "Block required for performance assertion" unless block_given?

  result = Benchmark.measure { yield }
  actual_duration = result.real

  message ||= "Expected block to complete in under #{max_duration}s, but took #{format("%.3f", actual_duration)}s"

  assert actual_duration <= max_duration, message

  actual_duration
end

#benchmark_block { ... } ⇒ Hash

Benchmark a block and return detailed timing information

Examples:

timing = benchmark_block do
  expensive_operation
end
puts "Real time: #{timing[:real]}s"

Yields:

  • Block to benchmark

Returns:

  • (Hash)

    Timing information with :real, :user, :system, :total keys

Raises:

  • (ArgumentError)


57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/ace/test_support/performance_helpers.rb', line 57

def benchmark_block
  raise ArgumentError, "Block required for benchmarking" unless block_given?

  result = Benchmark.measure { yield }

  {
    real: result.real,
    user: result.utime,
    system: result.stime,
    total: result.total
  }
end

#check_performance_regression(baseline_duration, tolerance: 1.5) { ... } ⇒ Boolean

Check if performance has regressed compared to baseline

Examples:

# Allow up to 50% slower than baseline
assert check_performance_regression(0.1) do
  my_operation
end

Parameters:

  • baseline_duration (Float)

    Expected baseline duration in seconds

  • tolerance (Float) (defaults to: 1.5)

    Acceptable tolerance factor (default: 1.5 = 50% slower allowed)

Yields:

  • Block to measure

Returns:

  • (Boolean)

    True if within tolerance, false if regressed

Raises:

  • (ArgumentError)


104
105
106
107
108
109
110
111
# File 'lib/ace/test_support/performance_helpers.rb', line 104

def check_performance_regression(baseline_duration, tolerance: 1.5)
  raise ArgumentError, "Block required for regression check" unless block_given?

  actual = benchmark_block { yield }[:real]
  max_allowed = baseline_duration * tolerance

  actual <= max_allowed
end

#compare_performance(label_a, label_b) {|comparison| ... } ⇒ Hash

Compare performance of two blocks

Examples:

compare_performance("old", "new") do |compare|
  compare.baseline { old_implementation }
  compare.candidate { new_implementation }
end

Parameters:

  • label_a (String)

    Label for first block

  • label_b (String)

    Label for second block

Yields:

  • (comparison)

Returns:

  • (Hash)

    Comparison results with :faster, :slower, :speedup keys

Raises:

  • (ArgumentError)


83
84
85
86
87
88
89
90
# File 'lib/ace/test_support/performance_helpers.rb', line 83

def compare_performance(label_a, label_b)
  raise ArgumentError, "Block required for performance comparison" unless block_given?

  comparison = PerformanceComparison.new(label_a, label_b)
  yield comparison

  comparison.execute
end