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.

Reply via email to