10 种 Python 编程优化技术。
优化代码至关重要,因为它直接影响软件的效率、性能和可扩展性。编写良好的代码运行速度更快、消耗更少的资源、更易于维护,使其更适合处理更大的工作负载并提升用户体验。由于高效的代码所需的处理能力和内存更少,它还能降低运营成本,这在资源有限的环境中尤为重要,例如嵌入式系统或大型云应用程序。
另一方面,编写糟糕的代码会导致执行时间变长、能耗增加以及基础设施成本上升。例如,在 Web 应用程序中,低效的代码会降低页面加载速度,导致用户体验不佳,甚至可能导致用户流失。在数据处理任务中,低效的算法会显著增加处理大型数据集所需的时间,从而延迟关键洞察和决策。
此外,优化的代码通常更易于维护和扩展。通过遵循优化最佳实践,开发人员可以确保其代码库保持简洁和模块化,从而更轻松地根据需要更新或扩展应用程序。随着软件项目复杂性的增加以及对系统需求的不断增长,这一点变得越来越重要。
让我们探索 10 种 Python 编程优化技巧,它们可以帮助您编写更高效、更高性能的代码。这些技巧对于开发满足性能需求、同时保持可扩展性和可维护性的健壮应用程序至关重要。通过遵循最佳实践,这些技巧也可以应用于其他编程语言。
1.变量包装
变量打包通过将多个数据项分组到单个结构中来最大限度地减少内存占用。这种技术在内存访问时间显著影响性能的场景中至关重要,例如在大规模数据处理中。将相关数据打包在一起可以更有效地利用 CPU 缓存,从而加快数据检索速度。
例子:
import struct
# Packing two integers into a binary format
packed_data = struct.pack('ii', 10, 20)
# Unpacking the packed binary data
a, b = struct.unpack('ii', packed_data)
在这个例子中,使用该struct
模块将整数打包成紧凑的二进制格式,使得数据处理更加高效。
2.存储与内存
理解存储(磁盘)和内存(RAM)之间的区别至关重要。内存操作速度更快但易失性更强,而存储具有持久性但速度更慢。在性能至关重要的应用程序中,将频繁访问的数据保存在内存中并最大限度地减少存储 I/O 对提高速度至关重要。
例子:
import mmap
# Memory-mapping a file
with open("data.txt", "r+b") as f:
mmapped_file = mmap.mmap(f.fileno(), 0)
print(mmapped_file.readline())
mmapped_file.close()
内存映射文件允许您将磁盘存储视为内存,从而加快大文件的访问时间。
3.固定长度变量与可变长度变量
固定长度变量存储在连续的内存块中,从而加快访问和操作速度。另一方面,可变长度变量需要额外的开销来管理动态内存分配,这会降低操作速度,尤其是在实时系统中。
例子:
import array
# Using fixed-length array for performance
fixed_array = array.array('i', [1, 2, 3, 4, 5])
# Dynamic list (variable-length)
dynamic_list = [1, 2, 3, 4, 5]
这里array.array
提供了一个固定长度的数组,比动态列表提供更可预测的性能。
4.内部职能与公共职能
内部函数是指仅在定义它们的模块内使用的函数,通常针对速度和效率进行了优化。公共函数则暴露给外部使用,可能包含额外的错误处理或日志记录,因此效率略低。
例子:
def _private_function(data):
# Optimized for internal use, with minimal error handling
return data ** 2
def public_function(data):
# Includes additional checks for external use
if isinstance(data, int):
return _private_function(data)
raise ValueError("Input must be an integer")
通过将大量计算保留在私有函数中,您可以优化代码的效率,并保留公共函数以确保外部安全性和可用性。
5.函数修饰符
在 Python 中,装饰器充当函数修饰符,允许你在函数主执行之前或之后添加功能。这对于缓存、访问控制或日志记录等任务非常有用,可以优化多个函数调用之间的资源使用率。
例子:
from functools import lru_cache
@lru_cache(maxsize=100)
def compute_heavy_function(x):
# A computationally expensive operation
return x ** x
用作lru_cache
装饰器可以缓存昂贵函数调用的结果,从而避免冗余计算,提高性能。
6.使用库
利用库可以避免重复造轮子。像 NumPy 这样的库是用 C 语言编写的,并且注重性能,因此与纯 Python 实现相比,它们在处理繁重的数值计算时效率更高。
例子:
import numpy as np
# Efficient matrix multiplication using NumPy
matrix_a = np.random.rand(1000, 1000)
matrix_b = np.random.rand(1000, 1000)
result = np.dot(matrix_a, matrix_b)
这里NumPy的dot
功能针对矩阵运算进行了增强,远远超过了纯Python中的嵌套循环。
7.短路条件
短路可以减少不必要的求值,这在复杂的条件检查或涉及资源密集型操作时尤其有用。它可以避免执行不需要检查的条件,从而节省时间和计算能力。
由于条件检查会在找到第一个满足条件的值后立即停止,因此您应该将最有可能使条件成立/不成立的变量放在最前面。在“或”条件(或)中,尝试将最有可能为真的变量放在最前面;在“与”条件(与)中,尝试将最有可能为假的变量放在最前面。一旦该变量被检查,条件语句就可以退出,而无需检查其他值。
例子:
def complex_condition(x, y):
return x != 0 and y / x > 2 # Stops evaluation if x is 0
x
在这个例子中,Python 的逻辑运算符确保只有非零时才执行除法,从而避免潜在的运行时错误和不必要的计算。
8.释放内存
对于长时间运行的应用程序,尤其是处理大型数据集的应用程序,一旦不再需要内存,就必须将其释放。可以使用del
、gc.collect()
或允许对象超出作用域来实现。
例子:
import gc
# Manual garbage collection to free up memory
large_data = [i for i in range(1000000)]
del large_data
gc.collect() # Forces garbage collection
使用gc.collect()
可确保及时回收内存,这在内存受限的环境中至关重要。
9.简短的错误信息
在内存或带宽有限的系统中,例如嵌入式系统或分布式应用程序中的日志记录,简短的错误消息可以减少开销。这种做法也适用于需要大规模错误日志记录的场景。
例子:
try:
result = 10 / 0
except ZeroDivisionError:
print("Err: Div/0") # Short, concise error message
简短的错误消息在资源效率至关重要的环境中很有用,例如物联网设备或高频交易系统。
10.优化循环
循环是效率低下的常见原因,尤其是在处理大型数据集时。通过减少迭代次数、简化逻辑或使用矢量化运算来优化循环可以显著提升性能。
例子:
import numpy as np
# Vectorised operation with NumPy
array = np.array([1, 2, 3, 4, 5])
# Instead of looping through elements
result = array * 2 # Efficient, vectorised operation
NumPy(数值 Python)是一个流行的 Python 库,用于数值和科学计算。它支持大型多维数组和矩阵,以及一系列用于操作这些数组的数学函数。
可以通过运行 pip 来安装它pip install numpy
。
矢量化消除了对显式循环的需要,利用低级优化来加快执行速度。
通过应用这些技术,您可以确保您的 Python 或其他编程语言程序运行速度更快、使用更少的内存并且更具可扩展性,这对于数据科学、Web 和系统编程中的应用程序尤其重要。
PS:您可以使用https://perfpy.com/#/来检查python代码效率。
文章来源:https://dev.to/jamesbright/10-python-programming-optimization-techniques-5ckf