博客
关于我
Python加速运行技巧
阅读量:797 次
发布时间:2023-03-07

本文共 3978 字,大约阅读时间需要 13 分钟。

Python代码加速运行的优化技巧

代码优化原则

在开始对 Python 代码进行优化之前,首先需要了解一些基本的优化原则。这些原则将帮助我们在不影响代码正确性的前提下,最大化地提升代码运行效率。

不要过早优化

很多开发者在编写代码时,总是急于进行性能优化。然而,过早地进行优化可能会导致以下问题:

  • 忽视代码的正确性
  • 在优化细节上耗费过多时间,而没有对整体性能进行全面评估
  • 优化的代价可能超过效率提升的价值

因此,在对代码进行优化之前,确保代码能够正确运行是至关重要的。只有在代码的正确性得到了保证的情况下,才能进行针对性的优化。

权衡优化的代价

优化是有代价的。任何优化都可能带来开发时间或维护成本的增加。例如:

  • 时间换空间:某些优化可能会使代码变得难以阅读
  • 空间换时间:某些优化可能会占用更多的内存空间
  • 开发代价:某些优化可能需要额外的开发工作

在进行优化时,需要权衡这些代价,选择最符合需求的优化方案。

不要优化无关紧要的部分

代码的优化不应该像微积分中的部分微调一样,盲目地对每一行代码进行优化。在实际应用中:

  • 代码的运行速度主要取决于执行次数最多的那部分代码
  • 对执行次数较少的代码进行优化,可能会带来微乎其微的性能提升
  • 不必要的优化可能会使代码更加难以维护和理解

因此,在优化代码之前,先要通过性能分析工具,找出真正导致性能瓶颈的代码部分,再对这些部分进行优化。


避免全局变量

在 Python 中,全局变量和局部变量的访问速度存在显著差异。全局变量的访问速度较慢,主要原因在于:

  • 全局变量的查找速度较慢,需要从程序的全局范围内搜索变量
  • 局部变量的查找速度较快,只需在函数的局部范围内搜索

因此,将代码中的全局变量尽量转化为局部变量,可以显著提升运行效率。

示例

不推荐写法:

import math
size = 10000
for x in range(size):
for y in range(size):
z = math.sqrt(x) + math.sqrt(y)

推荐写法:

import math
def 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 math
def computeSqrt(size):
result = []
sqrt = math.sqrt
for i in range(size):
result.append(sqrt(i))
return result
def main():
size = 10000
result = computeSqrt(size)
main()

推荐写法:

import math
def computeSqrt(size):
result = []
sqrt = math.sqrt
append = result.append
for i in range(size):
append(sqrt(i))
return result
def main():
size = 10000
result = computeSqrt(size)
main()

通过将 math.sqrtlist.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 List
def 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 List
def 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.jit
def 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/

你可能感兴趣的文章
python 按照当前日期创建文件
查看>>
Python 接口并发测试详解
查看>>
Python 接口自动化 —— requests框架
查看>>
python 接口自动化数据结构(如列表、字典、元组)
查看>>
Python 接口自动化测试中的深拷贝与浅拷贝~
查看>>
Python 接口自动化测试中的高阶函数
查看>>
python 控制 cmd 命令行颜色
查看>>
Python 操作 Azure Blob Storage
查看>>
Python 操作 Excel 全攻略 | 包括读取、写入、表格操作、图像输出和字体设置
查看>>
Python 操作 JMeter 探索:pymeter 实操指南
查看>>
Python 操作 Redis
查看>>
Python 操作Mysql(PyMysql)
查看>>
Python 操作Redis
查看>>
Python 操作sqlite数据库及保存查询numpy类型数据(一)
查看>>
Python 操作sqlite数据库及保存查询numpy类型数据(二)
查看>>
Python 操作数据库
查看>>
Python 数据分析与可视化实战
查看>>
python 数据可视化 -- matplotlib02
查看>>
python 数据可视化利器
查看>>
Python 数据可视化详解
查看>>