On Tue, Feb 22, 2011 at 12:40 AM, Keshav Kini <keshav.k...@gmail.com> wrote:
> On Feb 22, 3:08 pm, Robert Bradshaw <rober...@math.washington.edu>
> wrote:
>> On Mon, Feb 21, 2011 at 8:26 PM, Eviatar <eviatarb...@gmail.com> wrote:
>> > Importing in a loop is definitely not a good idea.
>>
>> Unless the loop is rarely executed...
>>
>> > I found this great guide about Python performance, including
>> > information about importing, lazy imports, and other issues:
>> >http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Import_Statem...
>>
>> The primary cost of imports is the initial import, which involves disk
>> access and execution of code (possibly importing other modules). If a
>> module is loaded in 5 different places, cutting out the import in only
>> 4 of them is not much of a savings. (Well, it could be in code
>> clarity.) Even if a module takes 1ms to load, loading 1000 of them
>> adds up, so think before importing modules that get pulled into
>> sage.all.
>>
>> In terms of where or what to import, here's my off-the-cuff
>> recommendation for Sage.
>>
>> 1. Import from the lowest level .all file you can. For example, to
>> import something from sage.rings.polynomial.Y into sage.rings.X, I'd
>> import it from sage.rings.polynomial.all, but from sage.foo.X, I'd
>> import it from sage.rings.all. This helps keep the dependencies clean
>> and easy to follow, as well as being the most future proof. Often I
>> try to avoid imports at all, e.g. use object methods like foo.sin()
>> rather than sin(foo) or QQ['x'] rather than PolynomailRing(QQ, 'x').
>>
>> 2. In terms of "import X; use X.foo" vs. "from X import foo," the
>> latter is faster, as it does not have to do a module lookup every
>> time. This can be especially true from Cython. If I use
>> "sage.rings.all.foo" then it has to lookup sage, lookup rings on that,
>> lookup all on that, and lookup foo on that. However, for infrequently
>> called functions (especially if it's not obvious from the symbol name
>> alone what it means), the full import path can lead to more legible
>> code.
>>
>> 3. If something is only going to be used once, or is expensive, it may
>> well be worth hiding that import in a function.
>>
>> 4.http://combinat.sagemath.org/doc/reference/sage/misc/lazy_import.html
>>
>> > Maybe it should be (at least partly) added to the Developer's Guide. I
>> > might do it when I have time.
>>
>> A link would probably be sufficient, rather than trying to duplicate
>> content. Of course, it would be a shame not to look at Cython if
>> performance becomes an issue, which is likely to have a much better
>> impact than some of these tips (though they're not bad).
>>
>> - Robert
>
> Thanks, this is very useful. One question I have - I was trying to
> write a new module in sage.graphs, and if I imported anything, whether
> by "from x import y" or "import x", it would add new stuff to my
> module's namespace unless I did the import inside a function. Is there
> a way to avoid this and still do the import outside all functions (so
> that the import is not called every time the function is)?

Even "import x" adds x to your module's namespace. Any top-level name
is in your module's namespace. However, why are you concerned about
this? We shouldn't be using "import *" from the "all" modules except
from other "all" modules to keep the global namespace clean. You can
also use __all__.

- Robert

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org

Reply via email to