On Tue, Mar 19, 2013 at 8:24 PM, Chris Smith <[email protected]> wrote: >>>>>> expand() is the worst. If we can make that faster, then all of SymPy >>>>>> will feel zippier. >>> >>> >>> This was done in the work for issue 1725, see > >> Perhaps you should separate those changes that add new features (like > ... >> part of some new API. For example, we should add some way for expand >> methods to register quick-exit handlers. > > > Wow, you did a good job of cleaning up expand. I just took a closer > look at it and see that much of what appeared to be redundant > recursion has been fixed by your expand cleanup. The only thing that > I think would make this significantly faster is to run all hints at > each subexpression of the tree rather than running each hit through > the whole tree.
Yes, each hint is now run exactly once per expansion, rather than dozens of times as before. But it still calls each hint recursively on every part of a symbolic tree. Most of the time, that just calls the no-op function that recurses down again, but it's still expensive, especially considering that 85% of the time it doesn't do anything at all. How would you propose to run each hint at once, especially given that some hints won't work until the other is run? Perhaps we should run each hint, but when a subexpression changes, be sure to run them in order so that nothing is missed? It would optimize for the common case (nothing changes). I also think that fast exiting might be worth trying. The expand hints that are run by default are mul, multinomial, power_base, power_exp, log, and basic. log is never relevant unless the expression contains a log. mul and multinomial are the most used, but they are only relevant if the expression contains Muls with Adds or a Pow with Add base and integer exp. power_base and power_exp I think are used occasionally, but not very often. basic is just a placeholder for functions that want expansion to run by default. I don't think it's used by much of anything library code. If expand knew all these "rules" for when expansions applied, it could get a very large expression like x1 + 2*A*x2 - B*x3 + ... (there are a lot expressions like these passed to expand in heurisch for example) that are already completely expanded, and it could quickly perform the necessary checks and determine that it is expanded without recursing through the whole expression tree. It would just need to perform expr.atoms(log, Mul, Pow) (should be fast, especially if it's run in parallel), and check each element of that for the corresponding rules. You might try just manually putting these rules in expand and profiling to see if it's really worth it (be sure to disable the cache when profile expand, though). Aaron Meurer > > -- > You received this message because you are subscribed to the Google Groups > "sympy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/sympy?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > > -- You received this message because you are subscribed to the Google Groups "sympy" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/sympy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
