4 ms·
Embedded DSLs in Python sometimes have a lot of overhead because of the way large expressions are built with operator overloading (x + y + z + ...), creating lo
by leethargo 7y ago
Embedded DSLs in Python sometimes have a lot of overhead because of the way large expressions are built with operator overloading (x + y + z + ...), creating lots of intermediate objects.
But there are solver-specific alternatives, such as for Gurobi or MOSEK that provide good performance, as well as vector-oriented modeling such as cvxpy.
Myself, I'm partial to Julia's JuMP as an embedded DSL that has good performance, a general purpose language and "nice" syntax, that is comparable to algebraic modeling languages.
- kragen 7y ago> Embedded DSLs in Python sometimes have a lot of overhead because of the way large expressions are built with operator overloading (x + y + z + ...), creating lots of intermediate objects. Is this really a concern in practice? My mental model is that the algebraic model is, you know, half a page to 10 pages of code without any loops or recursion, and you evaluate it to get an MPS file, and you feed that MPS file to your solver, which then chews on it for the next 15 seconds to 15 days. It's hard to imagine that Python's dynamic dispatch overhead would contribute more than a few milliseconds to this multi-day process. What am I missing?
- mochomocha 7y agoThere are low-latency applications of MIPs where such overheads matter. Sometimes one needs to solve small MIPs very often under strong latency requirements.
- twic 7y agoIndeed there are, but you don't to re-run the Python code expressing the model to do that. You build the model once, then tweak the numbers in the constraints and weights.
- anonsivalley652 7y agoThere's always rewriting in other languages or transpilation. If a framework is so crucial, not just for prototyping, perhaps the runtime components (as opposed to model building) could be ported to something like C, C++ or Rust.
- leethargo 7y agoTrue. For some classes of problems, code generation is actually used here: https://cvxgen.com/docs/index.html https://cvxgen.com/docs/index.html
- leethargo 7y agoI can't find a benchmark right now, but the specific issue with Python in this case was not dynamic dispatch, but memory allocation and GC. And yes, that lead to having the model creation time dominate the solve time by an order of magnitude. So it was a large-but-easy problem. Happens in particular when you use LP or QP, as opposed to MIP.
- leethargo 7y agoActually, see the issue described here: https://stackoverflow.com/questions/38434300/why-is-quicksum-very-slow-in-scip-python-interface https://stackoverflow.com/questions/38434300/why-is-quicksum... Using Python sum() is quite slow, so the packages provides a kind of lazy quicksum().