Skip to content

Performance

Performance is measured only after the corresponding correctness checks pass. Evaluation and fitting are reported separately because they exercise very different parts of the package.

The reference results below were obtained on an Apple Silicon macOS system with Julia 1.12.6, R 4.5.3, and rvinecopulib 0.7.3.1.0. They are useful for understanding the current performance profile, not as hardware-independent guarantees.

Evaluation benchmark

Run the standard battery with:

bash
bash benchmarks/run_main.sh

The current campaign uses   observations and three D-vine scenarios:

truncation
54
102
202

Vectorized log density

FamilyJuliarvinecopulibInterpretation
Gaussian514.0 ms21.9 msJulia 1.56× faster
Gaussian1016.8 ms33.0 msJulia 1.96× faster
Gaussian2037.9 ms72.0 msJulia 1.90× faster
Clayton513.7 ms18.8 msJulia 1.38× faster
Clayton1017.1 ms27.6 msJulia 1.62× faster
Clayton2039.3 ms61.8 msJulia 1.57× faster
Gumbel531.0 ms30.1 msnear parity
Gumbel1038.4 ms45.3 msJulia 1.18× faster
Gumbel2085.3 ms100.1 msJulia 1.17× faster
Frank520.8 ms15.6 msR 1.33× faster
Frank1024.0 ms21.9 msR 1.10× faster
Frank2054.8 ms49.0 msR 1.12× faster

Gaussian and Clayton are consistently faster in this battery. Gumbel is close to parity, while Frank log density is modestly faster in rvinecopulib.

Transforms and simulation

The transform profile is family-dependent:

FamilyRosenblattInverse RosenblattSimulation
Gaussianparity to Julia 1.36× fasterJulia 1.09–1.41× fasterJulia 1.07–1.44× faster
ClaytonJulia 1.08–1.45× fasterR 1.86–2.04× fasterR 1.88–2.06× faster
Gumbelparity to R 1.38× fasterR 1.60–1.82× fasterR 1.62–1.84× faster
FrankR 1.14–1.56× fasterJulia 8.92–11.98× fasterJulia 8.94–11.84× faster

This makes the current optimization targets clear: Clayton/Gumbel inverse h-function paths remain slower, while Frank inversion and simulation are particularly strong.

Numerical checks used with the timing battery

The evaluation runner also records numerical diagnostics. In the current campaign:

  • worst log-density maximum absolute difference:  ;

  • worst inverse_rosenblatt(rosenblatt(U)) maximum absolute error:  ;

  • worst rosenblatt(inverse_rosenblatt(Z)) maximum absolute error:  ;

  • largest numerical CDF QMC absolute difference:  .

CDF is estimated numerically, so its QMC discrepancy is not interpreted as an exact identity check. The strict cross-library correctness gate, rather than the timing battery, is the authority for release correctness.

Fitting benchmark

Fitting is currently the main performance gap. The benchmark uses  ,  , three timed repetitions after warm-up, and one thread on the R side.

Common model space

TaskJuliarvinecopulibInterpretation
Gaussian pair selection0.466 s0.137 sR 3.40× faster
Clayton pair selection0.448 s0.121 sR 3.71× faster
Fixed-structure R-vine4.419 s1.399 sR 3.16× faster
Automatic R-vine4.413 s1.334 sR 3.31× faster

Default model space

TaskJuliarvinecopulibInterpretation
Gaussian pair selection1.545 s0.213 sR 7.25× faster
Clayton pair selection1.554 s0.184 sR 8.45× faster
Fixed-structure R-vine14.740 s2.186 sR 6.74× faster
Automatic R-vine14.791 s2.133 sR 6.93× faster

The broader default family set substantially increases fitting cost in both implementations, but the increase is larger in VineCopulas.jl. This is therefore a performance target rather than a correctness issue: the corresponding   common and default correctness gates both pass.

The fixed and automatic rows should not be subtracted to estimate the cost of tree selection. They are end-to-end timings of two fitting paths, and small differences can be dominated by optimizer behavior and timing variability.

Student-t

Student-t is kept outside the standard table:

bash
bash benchmarks/tcopula_study/run_t_study.sh

The v0.1.1 reference run predates fused pair kernels. In that implementation, an active D-/R-vine edge evaluated density, hfunc1, and hfunc2 independently, requiring six base quantiles where two are sufficient. The fused Student pair step reuses those two quantiles for all three outputs.

The focused study reports both the independent and fused patterns, allocation counts, several degrees of freedom, and tail-heavy inputs. For Float32/Float64 inputs the Student hot path also uses direct Rmath qt/pt calls, while StatsFuns remains the legacy/comparison implementation and the fallback for nonstandard Real wrappers. This removes the allocation-heavy incomplete-beta inverse from ordinary vine evaluation without introducing an approximation.

A post-optimization Apple-Silicon/Julia-1.12.6 run reduced Student D-vine vectorized log-density from the pre-fusion 38.8/1192.6/3059 ms reference values to about 11.5/142.9/473.9 ms for (p,trunc)=(2,1),(5,4),(20,2). Against the same rvinecopulib benchmark this leaves gaps of about 5.1×, 2.55×, and 2.59×, respectively. The multi-tree cases therefore closed most of the previous 17–21× gap while preserving max absolute log-density agreement at roughly 1e-10 or better. End-to-end Student D-vine log-density now uses only 11 Julia allocations in all three cases; the remaining runtime is dominated by scalar Student CDF/quantile work rather than vine-engine allocation. Re-run the focused study and the correctness gate on the target machine before treating these machine-specific numbers as release benchmarks.