Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Utilities] improve performance of canonical #1704

Merged
merged 2 commits into from
Dec 14, 2021
Merged

[Utilities] improve performance of canonical #1704

merged 2 commits into from
Dec 14, 2021

Conversation

odow
Copy link
Member

@odow odow commented Dec 13, 2021

Initial analysis of jump-dev/JuMP.jl#2817

No changes to the memory allocations. But canonical gets called an awful lot, so this is a critical path. The current implementation was very generic with dynamic dispatch. But the functions aren't used outside MOI, or anywhere else in MOI:
https://juliahub.com/ui/Search?q=sort_and_compress%21&type=code
https://juliahub.com/ui/Search?q=is_strictly_sorted&type=code

Script:

using MathOptInterface
const MOI = MathOptInterface

function create_model(I, T = 10000)
    model = MOI.Utilities.Model{Float64}()
    v = MOI.VariableIndex[]
    for _ in 1:I
        x = MOI.add_variables(model, T)
        MOI.add_constraint.(model, x, MOI.GreaterThan(0.0))
        MOI.add_constraint.(model, x, MOI.LessThan(100.0))
        for t in 2:T
            f = MOI.ScalarAffineFunction(
                MOI.ScalarAffineTerm.([1.0, -1.0], [x[t], x[t-1]]),
                0.0,
            )
            MOI.add_constraint(model, f, MOI.GreaterThan(-10.0))
            MOI.add_constraint(model, f, MOI.LessThan(10.0))
        end
        append!(v, x)
    end
    g = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(1.0, v), 0.0)
    MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
    MOI.set(model, MOI.ObjectiveFunction{typeof(g)}(), g)
    return model
end

Before

julia> @benchmark create_model(100, 1000)
BenchmarkTools.Trial: 35 samples with 1 evaluation.
 Range (min  max):  113.697 ms  176.008 ms  ┊ GC (min  max):  0.00%  31.68%
 Time  (median):     146.131 ms               ┊ GC (median):    21.21%
 Time  (mean ± σ):   145.134 ms ±  15.243 ms  ┊ GC (mean ± σ):  20.95% ±  9.27%

  ▄                         █▄  ▁▁ ▁  ▁▄        ▁             ▁  
  █▆▁▁▁▆▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▆▁██▆▁██▆█▆▆██▁▁▁▆▁▁▆▁█▁▆▁▁▁▁▁▁▁▁▁▁▁█ ▁
  114 ms           Histogram: frequency by time          176 ms <

 Memory estimate: 77.28 MiB, allocs estimate: 799632.

After

julia> @benchmark create_model(100, 1000)
BenchmarkTools.Trial: 74 samples with 1 evaluation.
 Range (min  max):  48.633 ms  113.591 ms  ┊ GC (min  max):  0.00%  32.06%
 Time  (median):     67.296 ms               ┊ GC (median):    25.64%
 Time  (mean ± σ):   68.186 ms ±  10.339 ms  ┊ GC (mean ± σ):  24.84% ± 10.27%

        ▁             ▆ ▆▃█▁▃▆▁ ▃    ▁                          
  ▇▄▄▁▇▁█▁▄▁▁▁▁▁▁▄▁▇▄▇█▇███████▁█▄▄▇▄█▁▁▄▄▁▁▁▁▇▄▁▁▁▄▁▄▁▁▁▁▁▁▁▄ ▁
  48.6 ms         Histogram: frequency by time         94.1 ms <

 Memory estimate: 77.28 MiB, allocs estimate: 799632.

@odow odow added Submodule: Utilities About the Utilities submodule Type: Performance labels Dec 13, 2021
@odow odow merged commit 83f4c5e into master Dec 14, 2021
@odow odow deleted the od/perf-canonical branch December 14, 2021 01:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Submodule: Utilities About the Utilities submodule Type: Performance
Development

Successfully merging this pull request may close these issues.

1 participant