导入模块(但不使用)会降低Python性能吗?
我在用Django搭建一个网站,几乎在所有的脚本开头都导入了ipdb,这样调试的时候会方便很多。不过大部分时间我其实并不使用这个模块里的功能(只有在调试的时候才用到)。
我在想,这样做会不会影响我的网站性能?因为当我想设置一个断点的时候,我更喜欢写:
ipdb.set_trace()
而不是:
import ipdb; ipdb.set_trace()
不过我在很多地方看到过第二种写法,这让我有点好奇,哪种方式更高效呢……
我就是不太明白导入Python模块和效率之间的关系(假设你在脚本中并没有使用这个模块的方法)。
3 个回答
导入一个模块但不使用它会降低系统的性能:
- 导入模块需要时间
- 导入的模块会占用内存
第一个原因会让你的程序启动得更慢,而第二个原因可能会让你所有的程序都变慢,这取决于你电脑的内存总量。
简短回答:通常不会
详细回答:
加载模块是需要时间的。如果你是从网络驱动器或者其他比较慢的地方加载Python,可能会比较明显。但如果是直接从硬盘加载,你几乎不会察觉到。
正如@wRar所说,导入一个模块可能会执行很多代码。你可以在模块启动时执行任何你想要的代码。不过,大多数模块在启动时会避免执行过多的代码,所以这通常不是一个大问题。
不过,导入非常大的模块,尤其是那些还会引入很多C语言模块的,会花费更多时间。
所以,导入模块确实需要时间,但每个模块只需要一次。如果你在模块的顶部导入模块(而不是在函数内部),这只会影响启动时间。基本上,避免导入模块并不会给你带来太多的优化效果。
正如@wRAR提到的,加载一个模块可能意味着执行一些代码,这些代码可能需要花费不同的时间来完成。不过,这个模块只会被加载一次,之后再尝试导入时,系统会在os.sys.modules
中找到这个模块,并引用它。
在Django的调试模式下,模块会从Django的AppCache
中移除,只有在模块发生变化时才会重新导入。你可能不会在使用ipdb
时遇到这个问题,所以在你的情况下应该没什么影响。
不过,如果真的遇到问题,还有一些解决办法。假设你有一个自定义模块,你可以在这个模块里添加一个函数,只有在需要时才导入ipdb
:
# much used module: mymodule
def set_trace():
import ipdb
ipdb.set_trace()
在你想使用ipdb.set_trace
的模块中:
import mymodule
mymodule.set_trace()
或者,在你的模块顶部,使用跨模块的__debug__
变量:
if __debug__:
from ipdp import set_trace
else:
def set_trace(): return