From e8ef0dd4d3cddf91151a2566e84f3ec1279f09b2 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Wed, 11 Nov 2026 12:16:04 +0100 Subject: [PATCH] Use a comprehension in `_instantiate_operators` `_instantiate_operators` ran all of the work of the `MPOHamiltonian` constructors inside `map(collect(local_operators)) do term ... end`. Below that `map` call, type inference applies its recursion limit to every nested `map` over a vector whose element type is not concrete, such as `map(dual, S.spaces)` in `dual(::SumSpace)`. The limited results are not cached, so each function between the two `map` calls is inferred again at every call site (JuliaLang/julia#64862). A comprehension gives the same result without a `map` frame at the root. First call of `InfiniteMPOHamiltonian([P, P], (1, 2) => h, (2, 3) => h)` from that issue: | Julia | before | after | |---------------|------------------|------------------| | 1.10.13 | 10.7 s, 4.5 GiB | 9.4 s, 3.5 GiB | | 1.13.3 | 36.0 s, 16.7 GiB | 16.8 s, 7.6 GiB | | 1.14.0-alpha2 | 29.5 s, 16.4 GiB | 14.7 s, 7.9 GiB | Co-Authored-By: Claude Fable 5.2 --- docs/src/changelog.md | 3 +++ src/operators/mpohamiltonian.jl | 9 ++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/src/changelog.md b/docs/src/changelog.md index d608cfead..1213efe7b 100644 --- a/docs/src/changelog.md +++ b/docs/src/changelog.md @@ -31,6 +31,9 @@ When releasing a new version, move the "Unreleased" changes to a new version sec ### Performance +- Constructing an `MPOHamiltonian` from local operators compiles about twice as fast on + Julia 1.13 and 1.14. ([#554](https://github.com/QuantumKitHub/MPSKit.jl/pull/554)) + ## [0.14.1](https://github.com/QuantumKitHub/MPSKit.jl/compare/v0.14.0...v0.14.1) - 2026-11-02 ### Added diff --git a/src/operators/mpohamiltonian.jl b/src/operators/mpohamiltonian.jl index 4b724a4eb..c3f1c4b7d 100644 --- a/src/operators/mpohamiltonian.jl +++ b/src/operators/mpohamiltonian.jl @@ -513,9 +513,12 @@ of two proportional operators need not be related by that same scalar. """ function _instantiate_operators(lattice, local_operators) representatives = Tuple{Any, Any, Any}[] - return map(collect(local_operators)) do term - return instantiate_operator(lattice, _decompose_once!(representatives, term)) - end + # A comprehension rather than `map`: all of the work happens in here, and type inference + # limits `map` calls that are nested within another `map` (JuliaLang/julia#64862). + return [ + instantiate_operator(lattice, _decompose_once!(representatives, term)) + for term in collect(local_operators) + ] end # terms that are not supplied as an `inds => operator` pair -- e.g. a `LocalOperator` -- and