1

For example import math import's all function in math module whereas if we write from math import sqrt,pow then only sqrt(),pow() are imported.

Is their any performance or memory difference in both of them.

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
Hansie
  • 39
  • 7
  • If Python is designed properly, there shouldn't be any difference. – Robert Harvey Dec 27 '18 at 16:59
  • Have you run any tests to check the performance in each case? – Rory Daulton Dec 27 '18 at 16:59
  • 5
    Welcome to Stack Overflow! [Premature optimization is the root of all evil](http://c2.com/cgi/wiki?PrematureOptimization). Even if there's a difference, it will usually be negligible, so only worry about this when you actually have a performance problem. – Barmar Dec 27 '18 at 17:00
  • Welcome Hansie, If your question is unclear you will get downvoted and maybe put on [hold] until you refine your question. You can avoid downvotes by temporarily deleting the question, editing it into shape and undeleting afterwards. You question is speculative at best and hence off-topic - you might want to review [ask] and [help/on-topic] to make your questions better. Did you _observere and measure_ distinct differences between one and the other? This findings (and the [mcve] to reproduce it) might make this a better question. – Patrick Artner Dec 27 '18 at 17:05
  • Dupe: [use-import-module-or-from-module-import](https://stackoverflow.com/questions/710551/use-import-module-or-from-module-import) – Patrick Artner Dec 27 '18 at 17:11
  • @PatrickArtner "If your question is unclear you will get downvoted" What is not clear in my question to you ? – Hansie Dec 28 '18 at 06:07
  • @Hansi it is not clear that you "encountered" any problems with it - you did no testing or measuring. You did not import every module possible and look at the memory footprint of your python process when executing your code. The question itself is answered in the dupe (and there are several others on SO) hence it is unclear if you did any reasearch on this topic or if you simply placed to Question here to let the community brain solve it for you. – Patrick Artner Dec 28 '18 at 09:16
  • @PatrickArtner Thanks.I got the point.This was my first question.Next time i will come with some research and provide its details . – Hansie Dec 28 '18 at 12:59

1 Answers1

4

For example import math import's all function in math module whereas if we write from math import sqrt,pow then only sqrt(),pow() are imported.

It's a bit more complicated than that.

If we ignore for a moment that the math is built in into the interpreter (so there's nothing that has to be actually loaded), whether you do import math, from math import sqrt, pow or from math import *, the whole math module is loaded anyhow, and, after the import statement, it is present in sys.modules. So, it's not like there's more or less work to do for loading depending from how you import it.

The only difference between these constructs is the creation, in the import scope, of references to the names you mention in the import statement.

import math is probably the cheapest statement by itself, as it loads the module and just adds a local reference to the module object in the current scope; it essentially boils down to doing

math = __import__('math')

However, each usage is going to be more costly, as math.sin will need two dict lookups (one LOAD_GLOBAL and one LOAD_ATTR) if the import was at global scope, or one local variable lookup (LOAD_FAST) + one dict lookup (LOAD_ATTR) (if it was imported locally to a function) to actually reach the function object to invoke.

from math import sqrt, pow will cost a bit more, as it needs to load the module, look up sqrt and pow in it (two dict lookups) and create the corresponding entries in the scope where you imported them (two dict assignment if in global scope, two STORE_FAST local assignments if in function scope). It is equivalent to something like:

__temp = __import__('math')
sqrt = __temp.sqrt
pow = __temp.pow
del __temp

(__temp does not really exist, it's going to be just an object on the stack; sqrt and pow will be locals or globals depending from where the import statement has been issued)

On the other hand, on lookup this is going to be faster, as it needs only one dict lookup (LOAD_GLOBAL for global import) or one local lookup (LOAD_FAST for import local to a function) compared to the two above.

from math import * is the same as above, but for all the symbols provided in the module __all__ list (or all the symbols provided by the module period if no __all__ is specified).

From a memory standpoint, the latter two are going to cost more than the first, as they create more entries in the locals list or in the globals dict.

That being said, this kind of consideration is generally completely irrelevant, as we are talking about extremely small differences; what matters most when deciding how to import is how much pollution to your namespace is fine to allow in the name of less typing/less explicit imports.

Instead, the kind of optimization in these matters that usually counts is to bind frequently called functions to local variables to avoid continuous lookups in inner loops; for example

import math

def plot_it(framebuffer):
    sin = math.sin
    cos = math.cos
    for y in range(1024):
        for x in range(1024):
            framebuffer[y][x] = int(127*(sin(x)+cos(2*y)))

is generally going to be faster than doing math.sin and math.cos at each iteration, or even than importing sin and cos at top level in the file and using them straight inside the loop, as they are respectively two or one dict lookup away (to be done at each iteration), while here the interpreter just has to load two locals in the inner loop (which is very fast, it's just a straight array load).

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299