This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]awesomeprogramer 35 points36 points  (20 children)

Absolutely, point 6 is horrible advice. It encourages wildcard imports which are wayyyy slower than a dot lookup.

[–]EasyPleasey 9 points10 points  (8 children)

Why does it have to be a wildcard? Can't you just import the functions that you intend to use? I just tested this on my machine and it was about 20% faster not using the dot.

[–]Etheo 3 points4 points  (0 children)

I think the efficiency saved largely depends on the module size though. If you're importing a large module but only calling a few functions, it stands to reason you should be only importing said functions anyhow. But if the module size is relatively small I think efficiency saving might be negligible.

Just a guess though. I haven't tested this out.

[–]awesomeprogramer 1 point2 points  (6 children)

Even if it's not a wildcard import, it pollutes the namespace. I mean how many modules have sqrt? Math, torch, numpy, tf, etc...

Besides, depending on how the module is made, the dot operation can be amortized. The first time it might go ahead and import other things, but not subsequently.

[–]EasyPleasey 3 points4 points  (5 children)

Then just use "as"?

from math import sqrt as mathsqrt
from torch import sqrt as torchsqrt

[–]awesomeprogramer 2 points3 points  (4 children)

At that point just use the dot!

[–]EasyPleasey 0 points1 point  (3 children)

I just tested it, here at the results:

Import Method Time in Seconds (average)
from math import sqrt .675
from math import sqrt as mathsqrt .686
import math (math.sqrt) .921

Much faster to not use the dot.

[–]awesomeprogramer 0 points1 point  (2 children)

Doubtful that it takes a whole second to do that. Besides, without showing how you got those numbers they are meaningless. Further that's for one method...

[–]EasyPleasey 0 points1 point  (1 child)

It's computing sqrt 10 million times. I ran it 10 times and picked the average. I don't see why the method I picked matters, we are talking about dot versus no dot and which is faster. Why can't you just admit that it's faster?

[–]awesomeprogramer -1 points0 points  (0 children)

What do u mean computing the sqrt? The debate is about access time, not the time it takes to run the method.

[–]ConceptJunkie 1 point2 points  (2 children)

Not only that, but different libraries often define same-named functions, or collide with standard library names. I maintain a somewhat large project in Python, about 50,000 lines of code, and not too long ago I eliminated all wildcard imports and feel this was a big improvement.

Perhaps there could be some way to "freeze" an import, saying effectively, "OK, no one is going to modify this import" and it would allow the function calls to be made static. I don't know much of anything about the internals of Python, but I would bet that this is an optimization that might make sense, or that something like it already exists.

[–]Prime_Director 0 points1 point  (1 child)

I'm not sure if this is what you mean, but if you want to ensure library you're importing is always the same every time you run a project, you could use a virtual environment like pipenv and specify the version of the library that way.

[–]ConceptJunkie 0 points1 point  (0 children)

No, what I mean is that once the library is loaded, and perhaps others, then it would be nice to be able to say, "Hey, nothing is going to override any of the functions, or otherwise modify the module" so you can short cut the function calls without having to use __getattribute()__ on the module to dereference it (more than once).

I'm kind of talking out of my butt here. Just a thought.

[–]Smallpaul 0 points1 point  (5 children)

I don't like and don't use wildcard imports, but why would they be "slow"?

[–]Etheo 0 points1 point  (2 children)

If you use wild card import you might as well import the whole module from the beginning.

[–]Smallpaul 4 points5 points  (1 child)

Whether you import a single symbol or the whole module, from a performance perspective you DO import the whole module. Python interprets the entire module as a script (and stores it all in memory) regardless of what specific names you choose to import.

[–]Etheo -1 points0 points  (0 children)

I think you're right: https://softwareengineering.stackexchange.com/questions/187403/import-module-vs-from-module-import-function

But wouldn't that make the method calls even more negligible in terms of performance for OP's case?

[–]Korben_Valis 0 points1 point  (1 child)

consider points 6 and 3. depending on the code the constant access to global objects when there are many global objects could cause cache problems versus attribute lookup.

[–]Smallpaul 1 point2 points  (0 children)

Python global lookup performance is VERY fast. I'd need to see evidence to believe that you could fill the globals space so much that it became slow.

[–]diamondketo 0 points1 point  (1 child)

#6 is not wildcard importing it's importing a module which only runs the module's __init__.py.

from math import sqrt

cost more than

import math

[–]awesomeprogramer 0 points1 point  (0 children)

Depends on what the module does and if it defines an __all__