# Ldiv for Cholesky is slower than two substitutions

**URL:** <https://discourse.julialang.org/t/ldiv-for-cholesky-is-slower-than-two-substitutions/130092>\
**Category:** Performance\
**Created:** [June 21, 2025, 3:37pm UTC](https://discourse.julialang.org/t/ldiv-for-cholesky-is-slower-than-two-substitutions/130092 "2025-06-21T15:37:26Z")\
**Posts on this page:** 1\
**Showing post:** 9

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [June 22, 2025, 7:44pm UTC](https://discourse.julialang.org/t/ldiv-for-cholesky-is-slower-than-two-substitutions/130092/9 "2025-06-22T19:44:16Z")

</div>

> [@stepanzh](#):
>
> I have “infinite” time budget to prepare

Turns out it’s faster to avoid the extra preparation anyway. You can use an adjoint wrapper instead of materializing `L`, and the resulting computations are even faster:

```julia-repl
julia> function myldiv(chol, x)
           if chol.uplo == 'U'
               return ldiv!(chol.U, chol.U' \ x)
           elseif chol.uplo == 'L'
               return ldiv!(chol.L', chol.L \ x)
           else
               error("unreachable")
           end
       end
myldiv (generic function with 1 method)

julia> @benchmark myldiv($Achol, $b)
BenchmarkTools.Trial: 10000 samples with 1 evaluation per sample.
 Range (min … max): 120.500 μs … 276.959 μs ┊ GC (min … max): 0.00% … 0.00%
 Time (median): 129.959 μs ┊ GC (median): 0.00%
 Time (mean ± σ): 130.370 μs ± 8.761 μs ┊ GC (mean ± σ): 0.00% ± 0.00%

  ▂▁ █
  ██▆▄▅▅▅▄▄▄▃▃▃▃▃▃▃▄▄██▄▃▃▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▁▂▂▂▂▂▂▂▂▂▂▂ ▃
  120 μs Histogram: frequency by time 166 μs <

 Memory estimate: 8.00 KiB, allocs estimate: 1.

```

Compare this to my timings above for the `U \ (L \ $b)` version on the same computer:

```julia-repl
 Range (min … max): 132.750 μs … 227.459 μs ┊ GC (min … max): 0.00% … 0.00%
 Time (median): 145.292 μs ┊ GC (median): 0.00%
 Time (mean ± σ): 145.427 μs ± 5.723 μs ┊ GC (mean ± σ): 0.00% ± 0.00%

             ▁▁▄▄▄▄▄▄▃▂▄▄▄▄▆▅█▆▅▄▆▄▄▅▅▂▃
  ▁▁▁▁▂▃▄▅▄▇▇███████████████████████████▇▇▅▆▄▃▃▃▂▂▂▂▂▂▂▂▂▂▁▁▁▁▁ ▅
  133 μs Histogram: frequency by time 162 μs <

 Memory estimate: 16.00 KiB, allocs estimate: 2.

```

(Note that I used `ldiv!` to avoid an extra allocation in the new version, but that doesn’t significantly affect the timings, so the comparison is still valid. The O(N) allocation cost is dwarfed by the O(N^2) computation cost at this size.)

---

_[View the full topic](https://discourse.julialang.org/t/ldiv-for-cholesky-is-slower-than-two-substitutions/130092)._
