Consider:
>>> timeit.timeit('from win32com.client import Dispatch', number=100000)
0.18883283882571789
>>> timeit.timeit('import win32com.client', number=100000)
0.1275979248277963
It takes significantly longer to import only the Dispatch function rather than the entire module, which seems counter intuitive. Could someone explain why the overhead for taking a single function is so bad? Thanks!
The entire module still has to be imported to get the name you want from it...You'll also find that the OS is caching the module so subsequent access to the
.pyc
file will be quicker.The main issue here is that your code isn't timing what you think it is timing.
timieit.timeit()
will run theimport
statement in a loop, 100000 times, but at most the first iteration will actually perform the import. All other iterations simply look up the module insys.modules
, look up the nameDispatch
in the module's globals and add this name to the importing module's globals. So it's essentially only dictionary operations, and small variations in the byte code will become visible since there relative influence compared to the very cheap dictionary operations is big.If, on the other hand, you measure the time it takes to actually import the module, you can't see any difference between the two approaches, since in both cases this time is completely dominated by the actual import, and the differences fiddling around with the name dictionary become negligable. We can force reimports by deleting the module from
sys.modules
in each iteration:That's because:
is equivalent to:
But
from win32com.client import Dispatch
has its own advantages, for example if you're usingwin32com.client.Dispatch
multiple times in your code then it's better to assign it to a variable, so that number of lookups can be reduced. Otherwise each call towin32com.client.Dispatch()
will first search search forwin32com
and thenclient
insidewin32com
, and finallyDispatch
insidewin32com.client
.Byte-code comparison:
From the byte code it is clear that number of steps required for
from os.path import splitext
are greater than the simpleimport
.Module caching:
Note that after
from os.path import splitext
you can still access theos
module usingsys.modules
because python caches the imported modules.From docs:
Demo:
output:
Timing comparisons: