# Very slow performance when modifying and querying a model with JuMP

**URL:** <https://discourse.julialang.org/t/very-slow-performance-when-modifying-and-querying-a-model-with-jump/122842>\
**Category:** Optimization (Mathematical)\
**Tags:** question, jump\
**Created:** [November 20, 2024, 10:23am UTC](https://discourse.julialang.org/t/very-slow-performance-when-modifying-and-querying-a-model-with-jump/122842 "2024-11-20T10:23:51Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![njozefow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/njozefow/32/207654_2.png) [@njozefow](https://discourse.julialang.org/u/njozefow)\
**Post date:** [November 20, 2024, 10:23am UTC](https://discourse.julialang.org/t/very-slow-performance-when-modifying-and-querying-a-model-with-jump/122842/1 "2024-11-20T10:23:52Z")

</div>

Hello,

I have a question about the modifications and queries of a model with jump. If I use a jump model with set\_objective\_coefficient and set\_normalized\_coefficient, the computational times are 25 times slower than with a direct model.

Also, using normalized\_coefficient is very slow (about 7 to 9 seconds on my machine to query 10000 coefficients).

I have uploaded a code to this message illustrating the problem. The output that I have is :

```console
Set objective and constraint coefficients with model
 24.952014 seconds (20.13 M allocations: 1.075 GiB, 1.06% gc time, 0.06% compilation time)
Set objective and constraint coefficients with direct model
  1.001638 seconds (50.12 M allocations: 920.339 MiB, 3.52% gc time)
Read constraint coefficients with model
  7.129312 seconds (1.46 M allocations: 15.767 GiB, 5.58% gc time)
Read constraint coefficients with direct model
  8.741839 seconds (1.66 M allocations: 16.893 GiB, 5.37% gc time, 0.66% compilation time)

```

details: macos 15.0.01, julia 1.11.1, JuMP 1.23.4, Gurobi.jl 1.4.0, Gurobi 12.0

Remarks : using HiGHS, the modifications with the direct model are not much more efficient and the queries with the direct model are sky rocketing:

```console
Set objective and constraint coefficients with model
 25.451973 seconds (20.12 M allocations: 1.074 GiB, 1.86% gc time)
Set objective and constraint coefficients with direct model
Running HiGHS 1.8.1 (git hash: 4a7f24ac6): Copyright (c) 2024 HiGHS under MIT licence terms
 21.774826 seconds (20.18 M allocations: 465.435 MiB, 0.59% gc time, 0.21% compilation time)
Read constraint coefficients with model
  8.749680 seconds (1.46 M allocations: 15.767 GiB, 7.62% gc time, 0.06% compilation time)
Read constraint coefficients with direct model
156.650799 seconds (1.87 M allocations: 21.628 GiB, 0.76% gc time, 0.04% compilation time)

```

Do I do something wrong ?

Thank you in advance for any insight,

Best regards,

Nicolas.

```julia
module scjulia

using JuMP
using Gurobi

const GRB_ENV_REF = Ref{Gurobi.Env}()

function __init__ ()
    global GRB_ENV_REF
    GRB_ENV_REF[] = Gurobi.Env()
    return
end

function set_coefficient_model()
    create_optimizer() = Gurobi.Optimizer(GRB_ENV_REF[])
    model = Model(create_optimizer)

    @variable(model, x[1:10000])
    @constraint(model, constr[1:1000], 0 == 1)

    for i in eachindex(x)
        set_objective_coefficient(model, x[i], 1.0)
    end

    for i in eachindex(x), j in eachindex(constr)
        set_normalized_coefficient(constr[j], x[i], 1.0)
    end

    return model, x, constr
end

function set_coefficient_direct_model()
    model = direct_model(Gurobi.Optimizer(GRB_ENV_REF[]))

    @variable(model, x[1:10000])
    @constraint(model, constr[1:1000], 0 == 1)

    for i in eachindex(x)
        set_objective_coefficient(model, x[i], 1.0)
    end

    for i in eachindex(x), j in eachindex(constr)
        set_normalized_coefficient(constr[j], x[i], 1.0)
    end

    return model, x, constr
end

function read_coefficient_model(x, constr)
    @inbounds for i in 1:100, j in 1:100
        normalized_coefficient(constr[j], x[i])
    end
end

function read_coefficient_direct_model(x, constr)
    @inbounds for i in 1:100, j in 1:100
        normalized_coefficient(constr[j], x[i])
    end
end

function main()
    println("Set objective and constraint coefficients with model")
    @time model, x, constr = set_coefficient_model()
    println("Set objective and constraint coefficients with direct model")
    @time direct_model, direct_x, direct_constr = set_coefficient_direct_model()
    println("Read constraint coefficients with model")
    @time read_coefficient_model(x, constr)
    println("Read constraint coefficients with direct model")
    @time read_coefficient_direct_model(direct_x, direct_constr)
end

end # module scjulia

```

[scjulia.jl](https://discourse.julialang.org/uploads/short-url/3h6ZMcid6veKhILkctD7z8QQnKR.jl) (1.8 KB)

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [November 20, 2024, 7:49pm UTC](https://discourse.julialang.org/t/very-slow-performance-when-modifying-and-querying-a-model-with-jump/122842/2 "2024-11-20T19:49:28Z")

</div>

So my first question is _why_ do you want to do this? What are you really trying to do?

## Read coefficients

An improvement for all cases would be to query the constraint object once:

```julia
function read_coefficient(x, constr)
    for j in 1:100
        f_j = constraint_object(constr[j]).func
        for i in 1:100
            normalized_coefficient(f_j, x[i])
        end
    end
end

```

because the default implementation of `normalized_coefficient` is to query the full function and then extract a single number:

> <https://github.com/jump-dev/JuMP.jl/blob/bd93f37dff2e44a7fa563d94493db54482f65653/src/variables.jl#L3050-L3055>

## Gurobi

The Gurobi times look about what I expect. You’re setting 10\_000 objective coefficients, and 10\_000\_000 constraint coefficients, and your constraint is fully dense!

The first set with `Model` that takes 25 sec seems slow. I’ll take a look to see if we can improve that.

## HiGHS

Reading the constraint coefficients with direct model is a known issue: [GitHub · Where software is built](https://github.com/jump-dev/HiGHS.jl/issues/207)

---

<div class="post-metadata">

**Author:** ![njozefow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/njozefow/32/207654_2.png) [@njozefow](https://discourse.julialang.org/u/njozefow)\
**Post date:** [November 22, 2024, 12:09pm UTC](https://discourse.julialang.org/t/very-slow-performance-when-modifying-and-querying-a-model-with-jump/122842/3 "2024-11-22T12:09:39Z")

</div>

Hello,

Thank you for you reply.

Concerning the modification of the constraints, in a column generation approach instead of branching I enumerate all the missing variables and add them to the master. There can many new variables (up to 500 000 thousands) so it is not just a toy example on that aspect.

I agree with you that the 1s for the direct model is normal given the large number of coefficients that are modified. It is more the 25s for the standard models. In the actual algorithm, adding the new variables in the model (not direct) is much slower than the dynamic programming algorithm used to find the missing variable.

For the normalized\_coefficient function, I guessed I was using it wrongly (I used it as I would use the attribute query function directly in gurobi in C/C++). I do that for a cutting plane algorithm where I am used to read directly the information in the model instead of keeping additional data structures.

Best regards,

Nicolas.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [November 22, 2024, 7:51pm UTC](https://discourse.julialang.org/t/very-slow-performance-when-modifying-and-querying-a-model-with-jump/122842/4 "2024-11-22T19:51:55Z")

</div>

> instead of keeping additional data structures

You should keep additional data structures, or query the constraint function once.

JuMP does to have O(1) access to the constraint coefficients.

---

<div class="post-metadata">

**Author:** ![njozefow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/njozefow/32/207654_2.png) [@njozefow](https://discourse.julialang.org/u/njozefow)\
**Post date:** [November 26, 2024, 10:56am UTC](https://discourse.julialang.org/t/very-slow-performance-when-modifying-and-querying-a-model-with-jump/122842/5 "2024-11-26T10:56:34Z")

</div>

Thanks for the tip. I’ll use that instead.

N.
