MathOpt LinearTerm
v. LinearProduct
#4678
-
First off, thank you to the OR-Tools team for their hard work! I'm playing around with MathOpt in Python and noticed the documented difference between As such, I was wondering if there is any practical difference between expressions like Thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
For most users, how you build your model does not matter much. Write the simplest possible (often with operator overloads) that that is asymptotically optimal for model building and ignore constant factors. When you run the code, if you notice that model building time is a meaningful fraction of total time, and model build time + solving time is a meaningful fraction of application time (e.g. maybe reading the database to fetch you data is slower), then it is time to optimize (this is uncommon, but does happen). Some specific tips on improving Python performance: Calling mathopt.fast_sum(), rather than the build in Python sum(), will result in fewer objects being created to represent the expression tree (and solves some other issues and is recommended universally). The Model Builder API has a primitive for inner products that mathopt is missing, so doing sum_i a_i * x_i requires making an object for each multiplication, which can add up (similar to calling sum()). Re using LinearProduct vs LinearTerm, these objects appear to have ~the same size (both have two fields). If you are just multipling a constant times a variable, I would expect performance to be better with linear term, since there some extra structure we probably exploited somewhere to reduce the number of loops we need to run when we flatten an expression tree. If the expression building really is the bottleneck (typically only happens if you have already moved all your other computation to get organize your data into C++ via numpy, if you are writing loops in python this doesn't help), you can just bypass expressions all together and directly set coefficients on variables/constraints, but this will make your code harder to read. And setting each coefficient (at least in the newest version of ortools) will cause a language boundary crossing, which is also kind of expensive. Big picture, trying to optimize constant factors in Python is (IMO) a losing battle, as the language is not really designed for this. Having bulk operations via numpy to build your model (so all the work is done in C++) is a better way out than trying to micro optimize the very slow python code. We have some prototypes of this internally, no roadmap on if/when this will be submitted. We generally just use C++ directly if performance is an issue and cross the language boundary higher in the stack, but this is harder outside Google. |
Beta Was this translation helpful? Give feedback.
For most users, how you build your model does not matter much. Write the simplest possible (often with operator overloads) that that is asymptotically optimal for model building and ignore constant factors. When you run the code, if you notice that model building time is a meaningful fraction of total time, and model build time + solving time is a meaningful fraction of application time (e.g. maybe reading the database to fetch you data is slower), then it is time to optimize (this is uncommon, but does happen).
Some specific tips on improving Python performance: Calling mathopt.fast_sum(), rather than the build in Python sum(), will result in fewer objects being created to represent the …