sympy/sympy — pull request #1897 by smichr (2013-03-15 10:33:02+00:00)
Title: use bottom_up with expand_mul

The main key in keeping this fast is to not retrace the portions
of the tree already handled. Thus, calls to xm rather than
expand_mul are made, otherwise the traversal must start all over again.

**MASTER**
>>> eq=Mul(*[Add(*[Dummy() for i in range(3)])**[-1,1][random.random()<.5] for j in range(12)])
>>> [len(i.args) for i in eq.as_numer_denom()]
[5, 7]
>>> t=time();e2=expand_mul(sin(1+eq)+eq+2);time()-t
33.105345010757446

**NEW**

>>> eq=Mul(*[Add(*[Dummy() for i in range(3)])**[-1,1][random.random()<.5] for j in range(12)]);[len(i.args) for i in eq.as_numer_denom()]
[5, 7]
>>> t=time();e2=expand_mul(sin(1+eq)+eq+2);time()-t
1.7434329986572266

That was without cache (which might have helped because eq appeared
twice), but if we look at the time to just handle eq itself, the times
are not very different

>>> eq=Mul(*[Add(*[Dummy() for i in range(3)])**[-1,1][random.random()<.5] for j in range(12)]);[len(i.args) for i in eq.as_numer_denom()]
[5, 7]
>>> t=time();e2=expand_mul(eq);time()-t
1.6213688850402832