-
Notifications
You must be signed in to change notification settings - Fork 98
Closed
Labels
Milestone
Description
We know we have a time-to-first-solve problem. There have been a few different attempts at solving it (#1156, #1249, #1251, #1252), but they're getting a bit scattered, so I thought I would open an issue to track progress.
Currently, things are going in the wrong direction.
I'm going to argue that this benchmark is very important to users, particularly new users, and we should put a high priority on improving this. The script is setup to replicate how JuMP builds MOI models.
1.1.0
(base) oscar@Oscars-MBP time_to_first_solve % ~/julia --project=. script.jl clp
Running: clp
10.488984 seconds (28.36 M allocations: 1.654 GiB, 5.22% gc time, 15.34% compilation time)
0.001143 seconds (1.97 k allocations: 161.828 KiB)
(base) oscar@Oscars-MBP time_to_first_solve % ~/julia --project=. script.jl clp --no-bridge
Running: clp --no-bridge
4.820104 seconds (10.02 M allocations: 628.892 MiB, 4.53% gc time, 38.05% compilation time)
0.001012 seconds (2.43 k allocations: 221.797 KiB)
(base) oscar@Oscars-MBP time_to_first_solve % ~/julia --project=. script.jl glpk
Running: glpk
6.541374 seconds (17.35 M allocations: 1.026 GiB, 5.63% gc time, 28.40% compilation time)
0.000534 seconds (1.25 k allocations: 84.609 KiB)
(base) oscar@Oscars-MBP time_to_first_solve % ~/julia --project=. script.jl glpk --no-bridge
Running: glpk --no-bridge
4.013187 seconds (5.79 M allocations: 342.078 MiB, 4.16% gc time, 99.94% compilation time)
0.000375 seconds (680 allocations: 65.672 KiB)
0.10.6
(base) oscar@Oscars-MBP perf % ~/julia --project=. time_to_first_solve.jl clp
Running: clp
11.682708 seconds (27.87 M allocations: 1.710 GiB, 7.23% gc time, 11.85% compilation time)
0.001102 seconds (3.48 k allocations: 303.906 KiB)
(base) oscar@Oscars-MBP perf % ~/julia --project=. time_to_first_solve.jl clp --no-bridge
Running: clp --no-bridge
5.788850 seconds (12.06 M allocations: 744.691 MiB, 5.39% gc time, 13.72% compilation time)
0.001066 seconds (2.48 k allocations: 241.484 KiB)
(base) oscar@Oscars-MBP perf % ~/julia --project=. time_to_first_solve.jl glpk
Running: glpk
7.302795 seconds (18.49 M allocations: 1.082 GiB, 6.49% gc time, 22.80% compilation time)
0.000359 seconds (1.22 k allocations: 84.297 KiB)
(base) oscar@Oscars-MBP perf % ~/julia --project=. time_to_first_solve.jl glpk --no-bridge
Running: glpk --no-bridge
4.450319 seconds (8.48 M allocations: 498.214 MiB, 4.55% gc time, 99.97% compilation time)
0.000252 seconds (634 allocations: 67.031 KiB)
0.9.22
(base) oscar@Oscars-MBP auto-cache % ~/julia --project=. bench.jl clp
Running: clp
16.711929 seconds (36.79 M allocations: 2.105 GiB, 5.74% gc time, 45.43% compilation time)
0.001412 seconds (4.64 k allocations: 345.617 KiB)
(base) oscar@Oscars-MBP auto-cache % ~/julia --project=. bench.jl clp --no-bridge
Running: clp --no-bridge
10.783137 seconds (18.47 M allocations: 1.050 GiB, 5.39% gc time, 96.52% compilation time)
0.000804 seconds (2.09 k allocations: 177.289 KiB)
(base) oscar@Oscars-MBP auto-cache % ~/julia --project=. bench.jl glpk
Running: glpk
13.895745 seconds (31.22 M allocations: 1.786 GiB, 6.35% gc time, 53.08% compilation time)
0.000603 seconds (2.71 k allocations: 186.906 KiB)
(base) oscar@Oscars-MBP auto-cache % ~/julia --project=. bench.jl glpk --no-bridge
Running: glpk --no-bridge
10.406834 seconds (20.02 M allocations: 1.142 GiB, 5.85% gc time, 99.96% compilation time)
0.000545 seconds (2.01 k allocations: 162.797 KiB)
0.9.21
Running clp
21.338810 seconds (53.80 M allocations: 3.018 GiB, 6.56% gc time, 37.14% compilation time)
0.001744 seconds (5.96 k allocations: 535.180 KiB)
Running clp --no-bridge
10.575496 seconds (18.97 M allocations: 1.078 GiB, 5.09% gc time, 96.11% compilation time)
0.000997 seconds (3.02 k allocations: 309.555 KiB)
Running glpk
14.620199 seconds (33.51 M allocations: 1.916 GiB, 6.58% gc time, 53.13% compilation time)
0.000694 seconds (3.18 k allocations: 250.125 KiB)
Running glpk --no-bridge
11.557972 seconds (20.52 M allocations: 1.170 GiB, 4.85% gc time, 99.98% compilation time)
0.000487 seconds (2.52 k allocations: 234.297 KiB)
0.9.20
Running clp
15.997227 seconds (47.68 M allocations: 2.716 GiB, 9.29% gc time, 19.53% compilation time)
0.001548 seconds (3.43 k allocations: 279.242 KiB)
Running clp --no-bridge
5.052817 seconds (12.42 M allocations: 732.762 MiB, 6.70% gc time, 90.03% compilation time)
0.000808 seconds (1.84 k allocations: 174.609 KiB)
Running glpk
11.157795 seconds (35.30 M allocations: 2.023 GiB, 8.41% gc time, 27.83% compilation time)
0.000472 seconds (1.79 k allocations: 125.258 KiB)
Running glpk --no-bridge
7.441518 seconds (21.76 M allocations: 1.248 GiB, 6.89% gc time, 90.56% compilation time)
0.000337 seconds (1.39 k allocations: 127.336 KiB)
Script
setup.jl
import Pkg
if ARGS[1] == "v0.9.20"
Pkg.add([
Pkg.PackageSpec(name = "Clp"),
Pkg.PackageSpec(name = "GLPK"),
Pkg.PackageSpec(name = "MathOptInterface", version = v"0.9.20"),
])
elseif ARGS[1] == "v0.9.21"
Pkg.add([
Pkg.PackageSpec(name = "Clp"),
Pkg.PackageSpec(name = "GLPK"),
Pkg.PackageSpec(name = "MathOptInterface", version = v"0.9.21"),
])
elseif ARGS[1] == "master"
Pkg.add([
Pkg.PackageSpec(name = "Clp", rev = "od/moi10"),
Pkg.PackageSpec(name = "GLPK", rev = "od/moi10"),
Pkg.PackageSpec(name = "MathOptInterface", rev = "master"),
])
endbench.jl
using MathOptInterface, GLPK, Clp
const MOI = MathOptInterface
function example_diet(optimizer, bridge)
category_data = [
1800.0 2200.0;
91.0 Inf;
0.0 65.0;
0.0 1779.0
]
cost = [2.49, 2.89, 1.50, 1.89, 2.09, 1.99, 2.49, 0.89, 1.59]
food_data = [
410 24 26 730;
420 32 10 1190;
560 20 32 1800;
380 4 19 270;
320 12 10 930;
320 15 12 820;
320 31 12 1230;
100 8 2.5 125;
330 8 10 180
]
bridge_model = if bridge
MOI.instantiate(optimizer; with_bridge_type=Float64)
else
MOI.instantiate(optimizer)
end
model = MOI.Utilities.CachingOptimizer(
MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()),
MOI.Utilities.AUTOMATIC,
)
MOI.Utilities.reset_optimizer(model, bridge_model)
MOI.set(model, MOI.Silent(), true)
nutrition = MOI.add_variables(model, size(category_data, 1))
for (i, v) in enumerate(nutrition)
MOI.add_constraint(
model,
MOI.SingleVariable(v),
MOI.GreaterThan(category_data[i, 1]),
)
MOI.add_constraint(
model,
MOI.SingleVariable(v),
MOI.LessThan(category_data[i, 2]),
)
end
buy = MOI.add_variables(model, size(food_data, 1))
MOI.add_constraint.(model, MOI.SingleVariable.(buy), MOI.GreaterThan(0.0))
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(cost, buy), 0.0)
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
for (j, n) in enumerate(nutrition)
f = MOI.ScalarAffineFunction(
MOI.ScalarAffineTerm.(food_data[:, j], buy),
0.0,
)
push!(f.terms, MOI.ScalarAffineTerm(-1.0, n))
MOI.add_constraint(model, f, MOI.EqualTo(0.0))
end
MOI.optimize!(model)
term_status = MOI.get(model, MOI.TerminationStatus())
@assert term_status == MOI.OPTIMAL
MOI.add_constraint(
model,
MOI.ScalarAffineFunction(
MOI.ScalarAffineTerm.(1.0, [buy[end-1], buy[end]]),
0.0,
),
MOI.LessThan(6.0),
)
MOI.optimize!(model)
@assert MOI.get(model, MOI.TerminationStatus()) == MOI.INFEASIBLE
return
end
if length(ARGS) > 0
bridge = get(ARGS, 2, "") != "--no-bridge"
println("Running: $(ARGS[1]) $(get(ARGS, 2, ""))")
if ARGS[1] == "clp"
@time example_diet(Clp.Optimizer, bridge)
@time example_diet(Clp.Optimizer, bridge)
else
@assert ARGS[1] == "glpk"
@time example_diet(GLPK.Optimizer, bridge)
@time example_diet(GLPK.Optimizer, bridge)
end
exit(0)
endrun.sh
function run_benchmark() {
~/julia --project=. --depwarn=error bench.jl clp
~/julia --project=. --depwarn=error bench.jl clp --no-bridge
~/julia --project=. --depwarn=error bench.jl glpk
~/julia --project=. --depwarn=error bench.jl glpk --no-bridge
}
~/julia --project=. setup.jl v0.9.20
run_benchmark
~/julia --project=. setup.jl v0.9.21
run_benchmark
~/julia --project=. setup.jl master
run_benchmark
mlubin, blegat, joaquimg and dourouc05joaquimg and chriscoey