在众多编程语言中,Python 是通用性非常高的语言之一,同时具有简单性和可读性。 Python 因其易于阅读的语法、面向对象的特性、社区支持和大量的库而受到广泛的欢迎。它可用于数据分析、人工智能、Web开发、游戏开发等领域。
然而,与任何编程语言一样,Python 也拥有一定的劣势。其中之一是性能优化。由于其是解释语言的性质,开发人员总是对其速度和性能感到担忧。这正是代码优化发挥作用的地方。
Python 是一种解释性语言,这意味着它的运行速度不如类似C语言这样的编译语言 。但是,我们可以利用某些技术和策略来优化 Python 代码并提高其性能。
本文讲述了如何让 Python 代码运行得更快、更高效的一些原则。
在本文中,我们使用 Python 的 timeit 模块对代码执行的时间测量。
注意:timeit 模块默认运行该函数一百万次。
下面让我们一起来看看这些优化原则吧~
在 Python 2.7 和其以上版本中,增加了对列表、字典、集合使用生成器的功能,这些功能使得以更简洁和更有效的方式生成列表、字典和集合。
使用传统的循环方法创建一个函数并生成一个列表:
>>> def do_1():
... list_object = []
... for i in range(100):
... list_object.append(i)
导入 Python 内置timeit 模块来查看此函数运行多长时间:
>>> import timeit
>>> t = timeit.Timer(setup='from __main__ import do_1', stmt='do_1()')
>>> t.timeit()
5.526153074999996
上面的输出显示该函数大约需要5.52秒运行。
现在,使用生成器生成此列表并查看需要多长时间:
>>> def do():
... [i for i in range(100)]
>>> t = timeit.Timer(setup='from __main__ import do', stmt='do()')
>>> t.timeit()
2.805562479999992
从上面的代码中可以看出,该函数的运行时间大约为 2.81 秒。
从上述的推导式程序中可以看出,除了理解更简洁、更容易阅读之外,它也更快。这使得此方法成为生成列表和循环的首选方法。
使用 +=
运算符进行字符串连接是开发人员通常用来连接字符串的方法。但是,在循环内,由于字符串的不可变性质,它可能会很慢。
相反,请使用str.join()
方法来实现高效串联。
使用 +=
运算符连接字符串并查看其执行时间:
>>> def do():
... obj = ["hello", "my", "name", "is", "Delight", "!"]
... s = ""
... for elem in obj:
... s += elem
>>> import timeit
>>> t = timeit.Timer(setup='from __main__ import do', stmt='do()')
>>> t.timeit()
0.4512660080000046
使用 +=
运算符实现字符串连接,大约需要 0.45 秒才能完成。
使用 join()
来实现字符串拼接:
>>> def do():
... s = ["hello", "my", "name", "is", "Delight", "!"]
... "".join(s)
>>> import timeit
>>> t = timeit.Timer(setup='from __main__ import do', stmt='do()')
>>> t.timeit()
0.22072907100005068
使用join()
将函数的执行时间从0.45秒减少到0.22秒。
在大多数情况下,for 循环 可以替换为更高效的函数,称为 map()
。 map()
函数是一个内置的高阶函数,允许您将给定函数应用于可迭代的对象(例如列表、元组或字符串)。使用 map()
的主要优点是它提供了一种简洁高效的数据转换方法,无需显式循环。
传统的循环方式:
def do():
obj = ["hello", "my", "name", "is", "Delight", "!"]
new = []
for i in obj:
new.append(i.upper())
import timeit
t = timeit.Timer(setup='from __main__ import do', stmt='do()')
t.timeit()
0.26445533200012505
该函数执行了0.26秒。
使用map()
函数做相同的功能:
def square(x):
return x.upper()
def do():
obj = ["hello", "my", "name", "is", "Delight", "!"]
map(square, obj)
import timeit
t = timeit.Timer(setup='from __main__ import do', stmt='do()')
t.timeit()
0.21958118600014132
该函数用了0.22秒。
选择正确的数据结构会对 Python 代码的执行速度产生重大影响。不同的数据结构针对特定类型的操作进行了优化,选择合适的数据结构可以加快查找、插入、删除速度,并提高整体性能。
例如,判断容器内元素的时候,字典就比列表快的多。
>>> def do():
... fruits_list = ['apple', 'banana', 'orange', 'grape', 'pear']
... 'banana' in fruits_list
... 'kiwi' in fruits_list
>>> import timeit
>>> t = timeit.Timer(setup='from __main__ import do', stmt='do()')
>>> t.timeit()
0.24339481300014086
>>> def do():
... fruits_list = {'apple', 'banana', 'orange', 'grape', 'pear'}
... 'banana' in fruits_list
... 'kiwi' in fruits_list
>>> import timeit
>>> t = timeit.Timer(setup='from __main__ import do', stmt='do()')
>>> t.timeit()
0.18055910699990818
全局变量在跨程序共享数据方面发挥着重要作用。但是,应谨慎使用它们,并且仅在必要时使用。访问全局变量比访问局部变量慢。请注意始终尽量减少全局变量的使用,尤其是在循环内。
避免 Python 中不必要的函数调用对于提高代码的效率和性能非常重要。不必要的函数调用会带来开销、消耗内存并减慢程序的执行速度。尽可能组合操作。
避免 Python 中不必要的 import 语句对于维护干净、高效的代码至关重要。不必要的 import 有时会导致模块之间的循环依赖。
在本文中,我们介绍了优化Python代码的7个原则,这7个原则能够充分利用 Python 的潜力,提高Python代码执行效率。