On Sun, Sep 23, 2012 at 12:16 AM, Aaron Meurer <[email protected]> wrote: > Any fix that I can think up for this is somewhat fragile, so unless > someone can come up with something that clearly won't break anything, > I think I am going to leave this alone for now. I do think we should > try to do something about it, but doing it right before a release is > probably a bad idea. > > With that being said, my ideas so far are: > > - Wrap the imports in plot.py (and elsewhere) with something like > > global np, matplotlib > def _import_np_matplotlib(): > global np, matplotlib > np = import_module('numpy') > matplotlib = import_module('matplotlib') > > The issue here is that _import_np_matplotlib() has to be called before > np or matplotlib can be used (obviously), and for it to have any > effect, it must be inside a function call (not inside a class > definition). So I can put it at the top of the user-level functions > like plot(), but if someone tries to use the internal classes > directly, it won't work. > > - My other idea was to make import_module() return a lazy object, > which acts like the module, but doesn't actually import the module > until it is used. This works, but the problem is that to work > completely transparently, it has to import the module basically as > soon as it is touched. This means that the current code in plot.py, > which looks something like > > matplotlib = import_module("matplotlib") > if matplotlib: > plt = matplotlib.pyplot > # etc. > > still imports matplotlib right away, because the "if matplotlib" line > requires matplotlib to be imported (it's the only way to know if it is > installed). This particular case might be fixable with some more code > refactoring, but it just shows how fragile this approach is. If you > really want the module to only be imported when it is used, and not at > sympy import time, you have to be very careful about how you structure > the code. The only way to really know if you've done it right is to > check if importing sympy also imports matplotlib (by checking > sys.modules). And as this example shows, it's not always easy to > structure the code in this way. > > So if anyone has some ideas, I'd love to hear them. I know this > touches on some pretty advanced Python stuff, but even if you don't > know how stuff works but you have an abstract idea, I'd love to hear > it. If you are interested, I can push up my code with the lazy import > object.
See my deferred_import branch on GitHub. Comments welcome. I'm not going to open a pull request until I become convinced that this is something that we actually would want to include with SymPy. Aaron Meurer > > (By the way, another "fix" would be to not import the plotting module > by default. This I would rather not do) > > Aaron Meurer > > On Sat, Sep 22, 2012 at 8:13 PM, Aaron Meurer <[email protected]> wrote: >> I bisected it to this commit: >> >> commit 847bdfcb2c836d0e8853a9b985ef2bf88a925dd4 >> Author: Stefan Krastanov <[email protected]> >> Date: Tue Nov 15 19:54:25 2011 +0100 >> >> Adding plot function (not implemented) >> >> The docstring for the plot function is ready. The function itself is not >> ready. It just calls Plot with the same arguments. >> >> Also now the default between a contour plot and a 3d plot is the 3d plot. >> >> Also fixed some comments. >> >> which is the first commit where the new plotting module is imported >> with "import sympy". So I think the issue is that it imports numpy >> and matplotlib. We should restructure the module to only import those >> modules if the plotting module is used. Otherwise, we are making >> importing sympy too slow for the majority of users (who also have >> numpy and matplotlib installed). >> >> Aaron Meurer >> >> On Sat, Sep 22, 2012 at 7:41 PM, Aaron Meurer <[email protected]> wrote: >>> I was going through https://github.com/sympy/sympy/wiki/new-release in >>> preparation to cut the release candidate, when I get to the "speed of >>> import" section. I compared the test_import tool against SymPy 0.7.1 >>> and the 0.7.2 branch, and there appears to be a significant slow-down >>> (by almost 4x). >>> >>> Can other people reproduce this? If so, we need to figure out if it >>> is possible to bring this back down again. >>> >>> sympy(sympy-0.7.1)$%$./bin/test_import >>> Note: the first run (warm up) was not included in the average + std dev >>> All runs (including warm up): >>> [0.632580041885, 0.142980098724, 0.144616127014, 0.18177986145, >>> 0.153340816498, 0.146248817444, 0.152235031128, 0.147120952606, >>> 0.149618864059, 0.147889852524, 0.146507978439, 0.146991014481, >>> 0.148049116135, 0.149016857147, 0.146153926849, 0.149012088776, >>> 0.146345853806, 0.145620822906, 0.156076908112, 0.146780014038, >>> 0.148214817047, 0.146635055542, 0.148654937744, 0.14654302597, >>> 0.146838188171, 0.14808511734, 0.147293806076, 0.148097991943, >>> 0.149609804153, 0.148839950562, 0.147723913193, 0.146723985672, >>> 0.151859045029, 0.147171974182, 0.148344039917, 0.14845085144, >>> 0.147562980652, 0.151570081711, 0.200988054276, 0.150926113129, >>> 0.152683973312, 0.149338960648, 0.148150920868, 0.149286031723, >>> 0.146691083908, 0.147687911987, 0.145917892456, 0.14581489563, >>> 0.150799036026, 0.147582054138, 0.145636796951] >>> Number of tests: 50 >>> The speed of "import sympy" is: 0.149922 +- 0.008985 >>> sympy(sympy-0.7.1)$%$git co 0.7.2 >>> Previous HEAD position was 556fe55... SymPy 0.7.1 release >>> Switched to branch '0.7.2' >>> sympy0.7.2$%=$./bin/test_import >>> Note: the first run (warm up) was not included in the average + std dev >>> All runs (including warm up): >>> [1.01710915565, 0.398802042007, 0.396264076233, 0.397413015366, >>> 0.391931056976, 0.403698921204, 0.3991959095, 0.393259048462, >>> 0.411875009537, 0.397119045258, 0.414400100708, 0.465793132782, >>> 0.43417596817, 0.443454027176, 0.417393922806, 0.453384876251, >>> 0.400901079178, 0.393971920013, 0.39364695549, 0.393153905869, >>> 0.39675116539, 0.395659923553, 0.400503873825, 0.399799823761, >>> 0.406329870224, 0.393779039383, 0.400959968567, 0.392513036728, >>> 0.396237850189, 0.392780065536, 0.396032810211, 0.391910076141, >>> 0.396354913712, 0.393106937408, 0.514472961426, 0.428894042969, >>> 0.418586015701, 0.423231840134, 0.418197154999, 0.420174837112, >>> 0.414786100388, 0.420045852661, 0.438434839249, 0.424329996109, >>> 0.426602125168, 0.424081087112, 0.420931816101, 0.427915096283, >>> 0.418045043945, 0.421542882919, 0.424115896225] >>> Number of tests: 50 >>> The speed of "import sympy" is: 0.412739 +- 0.022607 >>> >>> Aaron Meurer -- You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/sympy?hl=en.
