InfiniteOpt.jl icon indicating copy to clipboard operation
InfiniteOpt.jl copied to clipboard

Remove the `DispatchVariableRef` Workflows

Open pulsipher opened this issue 4 years ago • 0 comments

Recent performance testing as revealed that the legacy dispatch_variable_ref paradigm of constantly creating DispatchVariableRefs from GeneralVariableRefs is adding a considerable amount of overhead. For example consider the simple query of the object_nums of a infinite variables.

using InfiniteOpt; m = InfiniteModel(); @infinite_parameter(m, t in [0, 1]); @variable(m, x[1:1000], Infinite(t));

function test1(vs)
    for v in vs
        vref = dispatch_variable_ref(v)
        m.infinite_vars[vref.index].variable.object_nums
    end
end

function test2(vs)
    for v in vs
        m.infinite_vars[InfiniteVariableIndex(v.raw_index)].variable.object_nums
    end
end
julia> @benchmark test1(x)
BenchmarkTools.Trial: 6638 samples with 1 evaluation.
 Range (min … max):  680.400 μs …   3.543 ms  ┊ GC (min … max): 0.00% … 78.11%
 Time  (median):     712.900 μs               ┊ GC (median):    0.00%        
 Time  (mean ± σ):   750.906 μs ± 220.740 μs  ┊ GC (mean ± σ):  2.36% ±  6.39%

  ▃▁▅▇▃█▆▅▄▂▂▁ ▂▂▂▁▂▃▅▃▃▃▁▁  ▁                                  ▂
  █████████████████████████████▇▇█▇▇▇█▇▇▆▆▆▆▅▃▆▆▅▁▄▅▄▁▅▅▃▃▅▃▃▅▃ █
  680 μs        Histogram: log(frequency) by time        120 ms <

 Memory estimate: 445.14 KiB, allocs estimate: 5489.

julia> @benchmark test2(x)
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
 Range (min … max):  122.100 μs …   2.782 ms  ┊ GC (min … max): 0.00% … 87.10%
 Time  (median):     134.200 μs               ┊ GC (median):    0.00%        
 Time  (mean ± σ):   170.004 μs ± 172.297 μs  ┊ GC (mean ± σ):  7.68% ±  7.24%

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

 Memory estimate: 390.62 KiB, allocs estimate: 3000.

Omitting the dispatch variable makes it 4 times faster. We can probably speed it up even more if we eliminate the need to create the index every time as well.

Hence, we should rework things to just dispatch based on a variable type stored in GeneralVariableRef so we don't have to reallocate. This will require that the entire code base be updated... Moreover, if we want to simplify the indices, we'll need to consider the unique case for dependent infinite parameters that need two indexing numbers.

pulsipher avatar Aug 20 '21 18:08 pulsipher