Skip to content

Performance improvements (allocations) - #397

Open
g-bauer wants to merge 3 commits into
mainfrom
vle-perf
Open

g-bauer wants to merge 3 commits into
mainfrom
vle-perf

Conversation

@g-bauer

@g-bauer g-bauer commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

These two commits remove most heap allocations from the evaluation of the residual PC-SAFT Helmholtz energy:

  • f9cd39e:
    • packing fractions directly lifted from the MonomerShape instead of materializing the geometry coefficients and the component index
    • computes zeta and d once and shares them between hard sphere, hard chain and dispersion contributions
    • no StateHD clone
    • sums the contributions without collecting them into a Vec
    • removes allocations in other places
  • b29b5dd:
    • the polar contributions use precomputed mean segment numbers and prefactors, and take zeta as input (as above mentioned)
    • cross-association reuses buffers for the Newton step and solves in place (we might ship such a buffered version to num-dual?)
    • iterator folds replace nalgebra operations that allocated in the hot loops

Timings & Allocations

For the 16 mixtures of Table 4 in the feos paper the first derivative of the residual Helmholtz energy is 2.5x to 7.1x faster now. The number of heap allocations per evaluation drops from 32–123 to 3–14.

Mixture Interactions before + f9cd39e + b29b5dd speedup allocations per evaluation
hexane / heptane non-polar 0.682 µs 0.157 µs 0.159 µs 4.3× 32 → 3 → 3
hexane / dimethyl ether dipole 1.011 µs 0.384 µs 0.184 µs 5.5× 48 → 13 → 3
hexane / acetylene quadrupole 1.013 µs 0.385 µs 0.185 µs 5.5× 48 → 13 → 3
hexane / 1-propanol association 0.916 µs 0.274 µs 0.276 µs 3.3× 40 → 5 → 5
acetone / heptane dipole 1.027 µs 0.381 µs 0.184 µs 5.6× 48 → 13 → 3
acetone / dimethyl ether dipole 1.146 µs 0.502 µs 0.219 µs 5.2× 50 → 15 → 3
acetone / acetylene dipole + quadrupole 1.682 µs 0.839 µs 0.238 µs 7.1× 80 → 33 → 3
acetone / 1-propanol dipole + association 1.252 µs 0.501 µs 0.303 µs 4.1× 56 → 15 → 5
carbon dioxide / heptane quadrupole 1.018 µs 0.385 µs 0.184 µs 5.5× 48 → 13 → 3
carbon dioxide / dimethyl ether dipole + quadrupole 1.682 µs 0.835 µs 0.238 µs 7.1× 80 → 33 → 3
carbon dioxide / acetylene quadrupole 1.141 µs 0.496 µs 0.220 µs 5.2× 50 → 15 → 3
carbon dioxide / 1-propanol quadrupole + association 1.244 µs 0.506 µs 0.302 µs 4.1× 56 → 15 → 5
ethanol / heptane association 0.908 µs 0.273 µs 0.276 µs 3.3× 40 → 5 → 5
ethanol / dimethyl ether association + dipole 1.262 µs 0.506 µs 0.303 µs 4.2× 56 → 15 → 5
ethanol / acetylene association + quadrupole 1.252 µs 0.503 µs 0.302 µs 4.1× 56 → 15 → 5
ethanol / 1-propanol cross-association 3.212 µs 2.551 µs 1.271 µs 2.5× 123 → 88 → 14

Time per evaluation of the first temperature derivative (Dual64) of the residual PC-SAFT Helmholtz energy, via cargo bench --profile=release-lto --bench=contributions. Apple M1 Pro, Rust 1.96. Allocations are heap blocks per evaluation, counted with dhat.

Interface changes

  • Breaking: MonomerShape::NonSpherical now holds &DVector<f64> instead of an owned DVector<D>.
  • Additive: new provided method ResidualDyn::reduced_residual_helmholtz_energy_density, which mirrors the method that already exists on Residual. EquationOfState and the ResidualDyn derive macro forward it, so models wrapped for Python take the allocation-free path as well.
  • Crate-internal: the signatures of HardChain, Dispersion, Dipole, Quadrupole and DipoleQuadrupole in pcsaft::eos.

computation out of individual contributions. Additional refactoring to
remove allocations in other places.
from num-dual (for now). Remove some nalgebra methods that allocate in
the hot loops in favor of iterator methods that do not allocate. Lift
zeta out of polar contributions. Refactor polar contributions to
eliminate repeated computations that can be done once.
@g-bauer g-bauer added enhancement New feature or request breaking Contains breaking changes labels Oct 16, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Contains breaking changes enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant