本文共 3978 字,大约阅读时间需要 13 分钟。
在开始对 Python 代码进行优化之前,首先需要了解一些基本的优化原则。这些原则将帮助我们在不影响代码正确性的前提下,最大化地提升代码运行效率。
很多开发者在编写代码时,总是急于进行性能优化。然而,过早地进行优化可能会导致以下问题:
因此,在对代码进行优化之前,确保代码能够正确运行是至关重要的。只有在代码的正确性得到了保证的情况下,才能进行针对性的优化。
优化是有代价的。任何优化都可能带来开发时间或维护成本的增加。例如:
在进行优化时,需要权衡这些代价,选择最符合需求的优化方案。
代码的优化不应该像微积分中的部分微调一样,盲目地对每一行代码进行优化。在实际应用中:
因此,在优化代码之前,先要通过性能分析工具,找出真正导致性能瓶颈的代码部分,再对这些部分进行优化。
在 Python 中,全局变量和局部变量的访问速度存在显著差异。全局变量的访问速度较慢,主要原因在于:
因此,将代码中的全局变量尽量转化为局部变量,可以显著提升运行效率。
不推荐写法:
import mathsize = 10000for x in range(size): for y in range(size): z = math.sqrt(x) + math.sqrt(y)
推荐写法:
import mathdef main(): size = 10000 for x in range(size): for y in range(size): z = math.sqrt(x) + math.sqrt(y)main()
通过将 math.sqrt 定义在局部变量中,可以将查找速度提升 15%-30%。
在 Python 中,属性访问操作符(.)会触发特定的方法(如 __getattribute__() 和 __getattr__()),这些方法会对变量进行额外的解析和操作,增加运行时间。
不推荐写法:
import mathdef computeSqrt(size): result = [] sqrt = math.sqrt for i in range(size): result.append(sqrt(i)) return resultdef main(): size = 10000 result = computeSqrt(size)main()
推荐写法:
import mathdef computeSqrt(size): result = [] sqrt = math.sqrt append = result.append for i in range(size): append(sqrt(i)) return resultdef main(): size = 10000 result = computeSqrt(size)main()
通过将 math.sqrt 和 list.append 赋值给局部变量,可以消除不必要的属性访问,提升运行效率。
在 Python 中,使用装饰器、属性访问器等对代码运行速度有一定的负面影响。这些机制会增加代码的执行时间,主要原因在于:
@property)会增加方法调用和内存分配的开销@property.setter)会增加属性设置的开销因此,只有在实际需要时,才应该使用这些抽象机制。
不推荐写法:
class DemoClass: def __init__(self, value): self._value = value @property def value(self): return self._value @value.setter def value(self, x): self._value = x
推荐写法:
class DemoClass: def __init__(self, value): self.value = value
通过直接使用属性而不是装饰器,可以显著提升代码运行速度。
在 Python 中,某些操作会导致不必要的数据复制,严重影响运行效率。以下是一些常见的优化方法:
def main(): size = 10000 for _ in range(size): value = range(size) value_list = [x for x in value] square_list = [x * x for x in value_list]
推荐写法:
def main(): size = 10000 value_list = [x for x in range(size)] square_list = [x * x for x in value_list]
通过直接使用生成器表达式,减少了不必要的数据复制,提升了运行效率。
if 条件的短路特性在 Python 中,if 条件的短路特性可以用来优化代码运行速度。具体方法如下:
from typing import Listdef concatString(string_list): abbreviations = {'cf.', 'e.g.', 'ex.', 'etc.', 'flg.', 'i.e.', 'Mr.', 'vs.'} result = '' abbreviations_count = 0 for str_i in string_list: if str_i in abbreviations: result += str_i return result 推荐写法:
from typing import Listdef concatString(string_list): abbreviations = {'cf.', 'e.g.', 'ex.', 'etc.', 'flg.', 'i.e.', 'Mr.', 'vs.'} result = ''.join([str_i for str_i in string_list if str_i in abbreviations]) return result 通过将 str_i in abbreviations 放在 if 条件的前面,可以充分利用短路特性,提升运行效率。
在 Python 中,for 循环比 while 循环更高效。以下是一些优化循环的建议:
def computeSum(size): sum_ = 0 i = 0 while i < size: sum_ += i i += 1 return sum_
推荐写法:
def computeSum(size): return sum(range(size))
通过使用 sum(range(size)),可以直接利用内置函数实现隐式 for 循环,大大提升了运行效率。
numba.jit通过使用 numba.jit,可以将 Python 函数编译为机器码,显著提升运行效率。以下是一个示例:
推荐写法:
import numba@numba.jitdef computeSum(size): sum_ = 0 for i in range(size): sum_ += i return sum_
通过 @numba.jit 装饰,可以将函数编译为机器码,大大提升了运行效率。
在 Python 中选择合适的数据结构对性能有重要影响。以下是一些常用的优化方法:
list):适合需要频繁添加、删除元素的场景,使用 deque 替代 list 更为高效。set):适合需要快速查找元素的场景,使用 bisect 模块可以加速查找。heapq):适合需要快速获取极小值或极大值的场景。通过合理选择数据结构,可以显著提升代码运行效率。
转载地址:http://thofk.baihongyu.com/