# Constructing JuMP problems is surprisingly slow

**URL:** <https://discourse.julialang.org/t/constructing-jump-problems-is-surprisingly-slow/63114>\
**Category:** Optimization (Mathematical)\
**Created:** [June 17, 2021, 9:43pm UTC](https://discourse.julialang.org/t/constructing-jump-problems-is-surprisingly-slow/63114 "2021-06-17T21:43:19Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Samuel\_Ainsworth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuel_ainsworth/32/15644_2.png) [@Samuel\_Ainsworth](https://discourse.julialang.org/u/Samuel_Ainsworth)\
**Post date:** [June 17, 2021, 9:43pm UTC](https://discourse.julialang.org/t/constructing-jump-problems-is-surprisingly-slow/63114/1 "2021-06-17T21:43:19Z")

</div>

I’m in a situation where I’d like to solve a lot of small nonlinear programming problems as quickly as possible. I’ve been surprised to find that JuMP model construction is much slower than I expected. I have a very small problem with 4 variables and 3 constraints, but JuMP model construction takes \>4.6 seconds:

```julia
import Ipopt
import JuMP
import MathOptInterface: MAX_SENSE

@time begin
  model = JuMP.Model(Ipopt.Optimizer)

  x_lo = JuMP.@variable(model, lower_bound=-2.0, upper_bound=0.1, start=0.1)
  x_hi = JuMP.@variable(model, lower_bound=0.1, upper_bound=2.0, start=0.1)

  y_lo = JuMP.@variable(model, lower_bound=-2.0, upper_bound=1.1, start=1.1)
  y_hi = JuMP.@variable(model, lower_bound=1.1, upper_bound=2.0, start=1.1)

  JuMP.add_NL_constraint(model, :(1.0 - ($(x_lo) * $(x_lo) + $(y_lo) * $(y_lo)) <= 0.0))
  JuMP.add_NL_constraint(model, :(0.0 - $(x_lo) <= 0.0))
  JuMP.add_NL_constraint(model, :(0.0 - $(y_lo) <= 0.0))

  JuMP.set_NL_objective(model, MAX_SENSE, :(($(x_hi) - $(x_lo)) * ($(y_hi) - $(y_lo))))
end

```

Granted, this may look a bit odd because I’m programmatically constructing these problems.

Ultimately, my goal is to be able to construct and solve a problem this small in \<10ms. What is taking so long here?

---

<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:** [June 17, 2021, 9:47pm UTC](https://discourse.julialang.org/t/constructing-jump-problems-is-surprisingly-slow/63114/2 "2021-06-17T21:47:59Z")

</div>

JuMP has a time-to-first-solve issue:  
[https://jump.dev/JuMP.jl/dev/tutorials/Getting%20started/performance\_tips/#The-"time-to-first-solve"-issue](https://jump.dev/JuMP.jl/dev/tutorials/Getting%20started/performance_tips/#The-%22time-to-first-solve%22-issue)

if you have to solve lots of small problems, you only pay the 4 seconds on the first one. The rest are very quick.

```nohighlight
julia> import Ipopt

julia> using JuMP

julia> function main()
         model = JuMP.Model(Ipopt.Optimizer)

         x_lo = JuMP.@variable(model, base_name="x_lo", lower_bound=-2.0, upper_bound=0.1, start=0.1)
         x_hi = JuMP.@variable(model, base_name="x_hi", lower_bound=0.1, upper_bound=2.0, start=0.1)

         y_lo = JuMP.@variable(model, base_name="y_lo", lower_bound=-2.0, upper_bound=1.1, start=1.1)
         y_hi = JuMP.@variable(model, base_name="y_hi", lower_bound=1.1, upper_bound=2.0, start=1.1)

         JuMP.add_NL_constraint(model, :(1.0 - ($(x_lo) * $(x_lo) + $(y_lo) * $(y_lo)) <= 0.0))
         JuMP.add_NL_constraint(model, :(0.0 - $(x_lo) <= 0.0))
         JuMP.add_NL_constraint(model, :(0.0 - $(y_lo) <= 0.0))

         JuMP.set_NL_objective(model, MOI.MAX_SENSE, :(($(x_hi) - $(x_lo)) * ($(y_hi) - $(y_lo))))
         return model
       end
main (generic function with 1 method)

julia> @time main();
  4.928089 seconds (1.51 M allocations: 86.285 MiB, 0.68% gc time, 99.97% compilation time)

julia> @time main();
  0.000409 seconds (1.94 k allocations: 113.305 KiB)

julia> @time main();
  0.000316 seconds (1.94 k allocations: 113.305 KiB)

```

---

<div class="post-metadata">

**Author:** ![Samuel\_Ainsworth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuel_ainsworth/32/15644_2.png) [@Samuel\_Ainsworth](https://discourse.julialang.org/u/Samuel_Ainsworth)\
**Post date:** [June 17, 2021, 9:49pm UTC](https://discourse.julialang.org/t/constructing-jump-problems-is-surprisingly-slow/63114/3 "2021-06-17T21:49:44Z")

</div>

I see… My problems do not all have the same structure (different numbers of constraints, etc). Does the warmup still help then?

---

<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:** [June 17, 2021, 9:53pm UTC](https://discourse.julialang.org/t/constructing-jump-problems-is-surprisingly-slow/63114/4 "2021-06-17T21:53:24Z")

</div>

> My problems do not all have the same structure (different numbers of constraints, etc). Does the warmup still help then?

It should be fine. The cost is compilation of functions based on their types. Not the numerical structure of the problems. Try it out and report any problems.

---

<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:** [June 17, 2021, 9:59pm UTC](https://discourse.julialang.org/t/constructing-jump-problems-is-surprisingly-slow/63114/5 "2021-06-17T21:59:43Z")

</div>

I’ll also say that if you just have quadratic expression, you can use `@objective` and `@constraint`. No need for this NL stuff.

```nohighlight
julia> import Ipopt

julia> using JuMP

julia> function main2()
           model = Model(Ipopt.Optimizer, bridge_constraints = false)
           @variables(model, begin
               -2.0 <= x_lo <= 0.1, (start = 0.1)
                0.1 <= x_hi <= 2.0, (start = 0.1)
               -2.0 <= y_lo <= 1.1, (start = 1.1)
                1.1 <= y_hi <= 2.0, (start = 1.1)
           end)
           @constraints(model, begin
               1 <= x_lo^2 + y_lo^2
               x_lo >= 0
               y_lo >= 0
           end)
           @objective(model, Max, (x_hi - x_lo) * (y_hi - y_lo))
           return model
       end
main2 (generic function with 1 method)

julia> @time main2();
  4.910041 seconds (1.24 M allocations: 70.148 MiB, 0.65% gc time, 99.97% compilation time)

julia> @time main2();
  0.000204 seconds (1.38 k allocations: 97.477 KiB)

julia> @time main2();
  0.000206 seconds (1.38 k allocations: 97.477 KiB)

```

---

<div class="post-metadata">

**Author:** ![Samuel\_Ainsworth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuel_ainsworth/32/15644_2.png) [@Samuel\_Ainsworth](https://discourse.julialang.org/u/Samuel_Ainsworth)\
**Post date:** [June 17, 2021, 10:29pm UTC](https://discourse.julialang.org/t/constructing-jump-problems-is-surprisingly-slow/63114/6 "2021-06-17T22:29:30Z")

</div>

Thanks! I have some problems that will automatically be constructed with nonlinear constraints, so I don’t know ahead of time whether or not it’s going to be friendly or not. But this is still good to know!
