Performance vs Echoes

Timings from scripts/bench_echoes/benchmark.jl: @belapsed on both sides, same machine, Echoes called through its Python API. t(E)/t(J) > 1 means MeanFieldHom is faster. Accuracy for the same runs is in Cross-validation.

Hill tensor $\mathbb P$

CaseJulia back-endEchoes$t(J)$$t(E)$$t(E)/t(J)$
sphere / ISOanalyticanalytic109 ns72.9 ms666 883×
prolate 5:1:1 / ISOanalyticanalytic308 ns108 ms351 014×
prolate 5:1:1 / ISO, rotatedanalyticanalytic740 ns104 ms141 083×
prolate 3:1:1 / cubic:residuesNUMINT3D4.41 ms95.8 ms21.7×
triaxial 2:1:0.5 / triclinic:residuesRESIDUES4.40 ms5.01 ms1.14×
triaxial 2:1:0.5 / triclinic:nestedquadgkNUMINT3D77.3 ms85.9 ms1.11×
triaxial 2:1:0.5 / triclinic:decuhrRESIDUES17.9 ms5.00 ms0.28×

Crack compliance $\mathbb H$

CaseJulia back-endEchoes$t(J)$$t(E)$$t(E)/t(J)$
penny / ISOanalyticanalytic26.2 µs55.7 ms2124×
penny / cubic:residuesNUMINT3D3.74 ms61.4 ms16.4×
penny / triclinic:residuesRESIDUES3.77 ms3.67 ms0.97×

Conductivity $\mathbb P^{(2)}$ and derivative $\partial\mathbb P/\partial\mathbb C$

Case$t(J)$$t(E)$$t(E)/t(J)$
sphere / iso $\mathbb K$73.4 ns10.1 µs138×
triaxial 2:1:0.5 / aniso $\mathbb K$6.50 µs14.8 µs2.27×
$\partial\mathbb P/\partial\mathbb C$, sphere / ISO (ForwardDiff vs closed form)904 ns12.5 µs13.8×
$\partial\mathbb P/\partial\mathbb C$, ORTHO, per component (NUMINT3D)5.8 ms94–141 ms16–24×

What the numbers say

  • Same algorithm ⇒ same speed. Residues against residues on a triclinic matrix: 1.14×, 0.97×, 0.98×. Neither implementation has a systematic edge.
  • The orders of magnitude come from dispatch, not from Julia. Isotropic and transversely-isotropic matrices take a closed-form branch (hill_tensor with method = :auto), where Echoes still integrates.
  • :decuhr is slower by design — an adaptive cubature kept as the type-generic, ForwardDiff-safe fallback, not a default.
  • AD costs nothing over a hand-coded derivative. ForwardDiff through hill_tensor beats Echoes' closed-form $\partial\mathbb P/\partial\mathbb C$ by 13.8× on the isotropic sphere.

Reproducing

import DECUHR, Integrals      # the :decuhr back-end lives in an extension
include("scripts/bench_echoes/benchmark.jl")

Internal (Julia-only) regression benchmarking is separate: scripts/bench/ holds a 67-case gated suite with a committed baseline and a bitwise checksum gate, described in its own README.md.