JuliaMath / HCubature.jl

pure-Julia multidimensional h-adaptive integration
Other
153 stars 25 forks source link

Performance improvements - allocs and times #44

Closed jwscook closed 1 year ago

jwscook commented 1 year ago

I was just investigating a performance problem with my code, which led me to investigate HCubature.jl. I made some small changes to pull out the first call, FirstEval, in front of hcubature_ to make a function barrier, which I think has helped enable Julia to compile better code(?). Either way, it looks like it's improved the allocations and timings on my machine on Version 1.8.3-pre.0, but it's definitely worth confirming that this improvement is not anomalous.

This branch:

julia> using HCubature, BenchmarkTools
[ Info: Precompiling HCubature [19dc6840-f33b-545b-b366-655c7e3ffd49]

julia> @benchmark hcubature(x -> cos(x[1])*cos(x[2]), [0,0], [1,1])
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
 Range (min … max):  26.951 μs …  3.035 ms  ┊ GC (min … max): 0.00% … 96.77%
 Time  (median):     27.893 μs              ┊ GC (median):    0.00%
 Time  (mean ± σ):   30.028 μs ± 55.798 μs  ┊ GC (mean ± σ):  3.60% ±  1.93%

  ▆█▆▅▃▁                                                      ▂
  ████████▇▆▆▆▆▅▆▆▆▆▅▅▅▅▃▅▅▅▄▁▃▄▁▄▄▄▄▄▅▅▅▄▅▄▄▅▄▄▆▄▃▅▃▁▁▅▃▄▄▅▃ █
  27 μs        Histogram: log(frequency) by time      62.3 μs <

 Memory estimate: 19.33 KiB, allocs estimate: 580.

On master v1.5.0:

julia> using HCubature, BenchmarkTools

julia> @benchmark hcubature(x -> cos(x[1])*cos(x[2]), [0,0], [1,1])
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
 Range (min … max):  47.759 μs …   4.363 ms  ┊ GC (min … max): 0.00% … 96.87%
 Time  (median):     49.287 μs               ┊ GC (median):    0.00%
 Time  (mean ± σ):   54.187 μs ± 103.596 μs  ┊ GC (mean ± σ):  5.51% ±  2.87%

  ▆█▆▄▃▂                                                       ▁
  ████████▇▆▇▇▇▆▆▅▆▆▅▅▆▅▄▅▅▃▅▅▅▄▅▅▄▄▄▃▄▁▅▄▅▄▅▅▄▁▄▅▄▆▅▄▅▅▄▄▁▄▄▅ █
  47.8 μs       Histogram: log(frequency) by time       106 μs <

 Memory estimate: 41.25 KiB, allocs estimate: 1045.
stevengj commented 1 year ago

I'm wary of adding a hack like this if there's not a clear understanding of why it works…

Is the problem here simply a lack of specialization on function arguments, that could be fixed by changing f to f::F and adding where {F}?

jwscook commented 1 year ago

Yep - that's the one. See #45.