Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions benchmark/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,18 @@ The `docs/make.jl` script will automatically detect and copy benchmark results f

The benchmark suite generates:

1. **results_ffta.json**: Raw benchmark data for FFTA.jl
2. **results_fftw.json**: Raw benchmark data for FFTW.jl
3. **benchmark_report.html**: Self-contained interactive HTML report with:
1. **results_ffta.json**: Raw benchmark data for FFTA.jl (complex FFT)
2. **results_fftw.json**: Raw benchmark data for FFTW.jl (complex FFT)
3. **results_ffta_rfft.json**: Raw benchmark data for FFTA.jl (real FFT)
4. **results_fftw_rfft.json**: Raw benchmark data for FFTW.jl (real FFT)
5. **benchmark_report.html**: Self-contained interactive HTML report with:
- Embedded JSON data
- Client-side Plotly.js charts (no external files needed)
- Combined Runtime/N vs N plot for all categories
- Absolute runtime plot for all categories
- Combined Runtime/N vs N plot for all categories (both complex and real FFT)
- Absolute runtime plot for all categories (both complex and real FFT)
- Individual plots for each category (odd/even powers of 2, powers of 3, composite, primes)
- Detailed results tables with speedup comparisons
- Separate sections for complex FFT and real FFT results

## Metrics

Expand Down Expand Up @@ -124,7 +127,11 @@ The benchmarks test various array sizes categorized by their mathematical struct
- Prime sizes require specialized FFT algorithms (e.g., Bluestein's algorithm)
- Logarithmic spacing ensures coverage from small to large primes

All tests use complex double-precision arrays (`ComplexF64`)
All tests are run for both:
- **Complex FFT**: Complex double-precision input arrays (`ComplexF64`)
- **Real FFT**: Real double-precision input arrays (`Float64`)

The real FFT (rfft) is optimized for real-valued input and exploits conjugate symmetry, typically achieving ~2x speedup over complex FFT for real data.

## Interpreting Results

Expand Down
55 changes: 51 additions & 4 deletions benchmark/ffta_env/bench_ffta.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ end
const SAMPLES = 100
const EVALS = 10

function benchmark_ffta()
function benchmark_ffta_complex()
results = Dict{String, Any}()
results["package"] = "FFTA"
results["fft_type"] = "complex"
results["data"] = []
results["categories"] = SIZE_CATEGORIES

println("Benchmarking FFTA.jl...")
println("Benchmarking FFTA.jl (Complex FFT)...")
println("=" ^ 50)

for n in ALL_SIZES
Expand Down Expand Up @@ -75,5 +76,51 @@ function benchmark_ffta()
return results
end

# Run benchmark
benchmark_ffta()
function benchmark_ffta_real()
results = Dict{String, Any}()
results["package"] = "FFTA"
results["fft_type"] = "real"
results["data"] = []
results["categories"] = SIZE_CATEGORIES

println("\nBenchmarking FFTA.jl (Real FFT)...")
println("=" ^ 50)

for n in ALL_SIZES
category = SIZE_CATEGORIES[n]
println("Testing array size: $n (category: $category)")

# Benchmark real FFT
x = randn(Float64, n)
trial = @benchmark rfft($x) samples=SAMPLES evals=EVALS

median_time = median(trial).time * 1e-9 # Convert to seconds
runtime_per_element = median_time / n

push!(results["data"], Dict(
"size" => n,
"category" => category,
"median_time" => median_time,
"runtime_per_element" => runtime_per_element,
"mean_time" => mean(trial).time * 1e-9,
"min_time" => minimum(trial).time * 1e-9,
"max_time" => maximum(trial).time * 1e-9
))

println(" Median time: $(median_time * 1e6) μs")
println(" Time per element: $(runtime_per_element * 1e9) ns")
end

# Save results to JSON
output_file = joinpath(@__DIR__, "..", "results_ffta_rfft.json")
open(output_file, "w") do io
JSON.print(io, results, 2)
end

println("\nResults saved to: $output_file")
return results
end

# Run benchmarks
benchmark_ffta_complex()
benchmark_ffta_real()
55 changes: 51 additions & 4 deletions benchmark/fftw_env/bench_fftw.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ end
const SAMPLES = 100
const EVALS = 10

function benchmark_fftw()
function benchmark_fftw_complex()
results = Dict{String, Any}()
results["package"] = "FFTW"
results["fft_type"] = "complex"
results["data"] = []
results["categories"] = SIZE_CATEGORIES

println("Benchmarking FFTW.jl...")
println("Benchmarking FFTW.jl (Complex FFT)...")
println("=" ^ 50)

for n in ALL_SIZES
Expand Down Expand Up @@ -73,5 +74,51 @@ function benchmark_fftw()
return results
end

# Run benchmark
benchmark_fftw()
function benchmark_fftw_real()
results = Dict{String, Any}()
results["package"] = "FFTW"
results["fft_type"] = "real"
results["data"] = []
results["categories"] = SIZE_CATEGORIES

println("\nBenchmarking FFTW.jl (Real FFT)...")
println("=" ^ 50)

for n in ALL_SIZES
category = SIZE_CATEGORIES[n]
println("Testing array size: $n (category: $category)")

# Benchmark real FFT
x = randn(Float64, n)
trial = @benchmark rfft($x) samples=SAMPLES evals=EVALS

median_time = median(trial).time * 1e-9 # Convert to seconds
runtime_per_element = median_time / n

push!(results["data"], Dict(
"size" => n,
"category" => category,
"median_time" => median_time,
"runtime_per_element" => runtime_per_element,
"mean_time" => mean(trial).time * 1e-9,
"min_time" => minimum(trial).time * 1e-9,
"max_time" => maximum(trial).time * 1e-9
))

println(" Median time: $(median_time * 1e6) μs")
println(" Time per element: $(runtime_per_element * 1e9) ns")
end

# Save results to JSON
output_file = joinpath(@__DIR__, "..", "results_fftw_rfft.json")
open(output_file, "w") do io
JSON.print(io, results, 2)
end

println("\nResults saved to: $output_file")
return results
end

# Run benchmarks
benchmark_fftw_complex()
benchmark_fftw_real()
Loading
Loading