高效编程技巧:提升 Python 代码性能的秘籍

目录

一、引言

二、选择合适的数据结构

(一)列表与集合的选择

(二)字典与默认字典

三、优化算法与代码逻辑

(一)减少循环中的计算

(二)使用生成器表达式

四、利用 Python 的内置函数和库

(一)使用内置函数

(二)使用优化的第三方库

五、总结


一、引言

Python 作为一种广泛应用的编程语言,以其简洁、易读的语法和丰富的库而备受开发者喜爱。然而,在处理大规模数据或对性能要求较高的场景中,Python 代码的性能可能成为瓶颈。本文将深入探讨一系列提升 Python 代码性能的实用技巧,帮助开发者编写出高效、优化的代码。

二、选择合适的数据结构

(一)列表与集合的选择

列表(list)和集合(set)在 Python 中都用于存储多个元素,但它们的内部实现和性能特点有所不同。列表是有序的可变序列,适合需要保留元素顺序的场景。例如,在遍历一个按特定顺序排列的数据集合时,列表是较好的选择。然而,在进行成员检查(如判断某个元素是否在集合中)时,列表的时间复杂度为 O (n),随着元素数量的增加,检查时间会显著增长。

集合是无序的可变容器,它基于哈希表实现,成员检查的时间复杂度为 O (1),在需要频繁进行成员检查的场景下,集合的性能优势明显。比如,在处理大量用户 ID,需要快速判断某个 ID 是否存在时,使用集合能大幅提高效率。

 

# 列表成员检查示例

my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

import timeit

start_time = timeit.default_timer()

for _ in range(10000):

if 5 in my_list:

pass

end_time = timeit.default_timer()

print(f"列表成员检查时间: {end_time - start_time}")

# 集合成员检查示例

my_set = set(my_list)

start_time = timeit.default_timer()

for _ in range(10000):

if 5 in my_set:

pass

end_time = timeit.default_timer()

print(f"集合成员检查时间: {end_time - start_time}")

# 列表成员检查示例

my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

import timeit

start_time = timeit.default_timer()

for _ in range(10000):

if 5 in my_list:

pass

end_time = timeit.default_timer()

print(f"列表成员检查时间: {end_time - start_time}")

# 集合成员检查示例

my_set = set(my_list)

start_time = timeit.default_timer()

for _ in range(10000):

if 5 in my_set:

pass

end_time = timeit.default_timer()

print(f"集合成员检查时间: {end_time - start_time}")

# 列表成员检查示例

my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

import timeit

start_time = timeit.default_timer()

for _ in range(10000):

if 5 in my_list:

pass

end_time = timeit.default_timer()

print(f"列表成员检查时间: {end_time - start_time}")

# 集合成员检查示例

my_set = set(my_list)

start_time = timeit.default_timer()

for _ in range(10000):

if 5 in my_set:

pass

end_time = timeit.default_timer()

print(f"集合成员检查时间: {end_time - start_time}")

运行上述代码,会发现集合的成员检查速度远远快于列表。

(二)字典与默认字典

字典(dict)是 Python 中常用的键值对存储结构,它提供了快速的查找和插入操作,时间复杂度平均为 O (1)。在某些情况下,当访问不存在的键时,我们希望字典能返回一个默认值,这时可以使用默认字典(defaultdict)。默认字典是字典的子类,在创建时需要传入一个可调用对象(如 int、list、set 等)作为默认值的生成器。

 

from collections import defaultdict

# 普通字典访问不存在键的情况

my_dict = {}

try:

value = my_dict['non_existent_key']

except KeyError:

value = 0

my_dict['non_existent_key'] = value

# 默认字典访问不存在键的情况

my_default_dict = defaultdict(int)

value = my_default_dict['non_existent_key']

from collections import defaultdict

# 普通字典访问不存在键的情况

my_dict = {}

try:

value = my_dict['non_existent_key']

except KeyError:

value = 0

my_dict['non_existent_key'] = value

# 默认字典访问不存在键的情况

my_default_dict = defaultdict(int)

value = my_default_dict['non_existent_key']

from collections import defaultdict

# 普通字典访问不存在键的情况

my_dict = {}

try:

value = my_dict['non_existent_key']

except KeyError:

value = 0

my_dict['non_existent_key'] = value

# 默认字典访问不存在键的情况

my_default_dict = defaultdict(int)

value = my_default_dict['non_existent_key']

使用默认字典可以简化代码,避免繁琐的键存在性检查,同时在一定程度上提高代码的执行效率。

三、优化算法与代码逻辑

(一)减少循环中的计算

在循环中,应尽量减少不必要的计算。将循环内的常量计算或不依赖循环变量的计算移到循环外部。例如:

 

# 未优化的代码

result = []

for i in range(1000):

factor = 2 * 3.14159

value = i * factor

result.append(value)

# 优化后的代码

factor = 2 * 3.14159

result = []

for i in range(1000):

value = i * factor

result.append(value)

# 未优化的代码

result = []

for i in range(1000):

factor = 2 * 3.14159

value = i * factor

result.append(value)

# 优化后的代码

factor = 2 * 3.14159

result = []

for i in range(1000):

value = i * factor

result.append(value)

# 未优化的代码

result = []

for i in range(1000):

factor = 2 * 3.14159

value = i * factor

result.append(value)

# 优化后的代码

factor = 2 * 3.14159

result = []

for i in range(1000):

value = i * factor

result.append(value)

在上述示例中,将常量计算移到循环外,避免了在每次循环时重复计算,从而提高了代码性能。

(二)使用生成器表达式

生成器表达式是一种简洁高效的创建生成器的方式。与列表推导式相比,生成器表达式不会立即生成整个列表,而是在迭代时逐个生成元素,因此更节省内存。例如,计算 1 到 1000000 的平方和,可以使用生成器表达式:

 

# 使用列表推导式

import timeit

start_time = timeit.default_timer()

squares_list = [i**2 for i in range(1, 1000001)]

sum_squares_list = sum(squares_list)

end_time = timeit.default_timer()

print(f"列表推导式计算时间: {end_time - start_time}")

# 使用生成器表达式

start_time = timeit.default_timer()

sum_squares_generator = sum(i**2 for i in range(1, 1000001))

end_time = timeit.default_timer()

print(f"生成器表达式计算时间: {end_time - start_time}")

# 使用列表推导式

import timeit

start_time = timeit.default_timer()

squares_list = [i**2 for i in range(1, 1000001)]

sum_squares_list = sum(squares_list)

end_time = timeit.default_timer()

print(f"列表推导式计算时间: {end_time - start_time}")

# 使用生成器表达式

start_time = timeit.default_timer()

sum_squares_generator = sum(i**2 for i in range(1, 1000001))

end_time = timeit.default_timer()

print(f"生成器表达式计算时间: {end_time - start_time}")

# 使用列表推导式

import timeit

start_time = timeit.default_timer()

squares_list = [i**2 for i in range(1, 1000001)]

sum_squares_list = sum(squares_list)

end_time = timeit.default_timer()

print(f"列表推导式计算时间: {end_time - start_time}")

# 使用生成器表达式

start_time = timeit.default_timer()

sum_squares_generator = sum(i**2 for i in range(1, 1000001))

end_time = timeit.default_timer()

print(f"生成器表达式计算时间: {end_time - start_time}")

运行结果表明,生成器表达式在计算效率和内存使用上都优于列表推导式。

四、利用 Python 的内置函数和库

(一)使用内置函数

Python 的内置函数经过高度优化,运行效率通常比自定义函数高。例如,在对列表进行排序时,应优先使用内置的 sorted 函数,而不是自己编写排序算法。

 

my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]

# 自定义排序函数(简单冒泡排序示例,效率较低)

def custom_sort(lst):

n = len(lst)

for i in range(n):

for j in range(0, n - i - 1):

if lst[j] > lst[j + 1]:

lst[j], lst[j + 1] = lst[j + 1], lst[j]

return lst

import timeit

start_time = timeit.default_timer()

custom_sort(my_list)

end_time = timeit.default_timer()

print(f"自定义排序时间: {end_time - start_time}")

start_time = timeit.default_timer()

sorted(my_list)

end_time = timeit.default_timer()

print(f"内置sorted函数排序时间: {end_time - start_time}")

my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]

# 自定义排序函数(简单冒泡排序示例,效率较低)

def custom_sort(lst):

n = len(lst)

for i in range(n):

for j in range(0, n - i - 1):

if lst[j] > lst[j + 1]:

lst[j], lst[j + 1] = lst[j + 1], lst[j]

return lst

import timeit

start_time = timeit.default_timer()

custom_sort(my_list)

end_time = timeit.default_timer()

print(f"自定义排序时间: {end_time - start_time}")

start_time = timeit.default_timer()

sorted(my_list)

end_time = timeit.default_timer()

print(f"内置sorted函数排序时间: {end_time - start_time}")

my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]

# 自定义排序函数(简单冒泡排序示例,效率较低)

def custom_sort(lst):

n = len(lst)

for i in range(n):

for j in range(0, n - i - 1):

if lst[j] > lst[j + 1]:

lst[j], lst[j + 1] = lst[j + 1], lst[j]

return lst

import timeit

start_time = timeit.default_timer()

custom_sort(my_list)

end_time = timeit.default_timer()

print(f"自定义排序时间: {end_time - start_time}")

start_time = timeit.default_timer()

sorted(my_list)

end_time = timeit.default_timer()

print(f"内置sorted函数排序时间: {end_time - start_time}")

显然,内置的 sorted 函数在排序效率上远超自定义的简单冒泡排序函数。

(二)使用优化的第三方库

对于数值计算、科学计算等任务,使用经过优化的第三方库能显著提升性能。例如,NumPy 库针对数组操作进行了高度优化,其底层使用 C 语言实现,相比纯 Python 的列表操作,速度有数量级的提升。

 

import numpy as np

import timeit

# 纯Python列表计算

my_list = list(range(1, 1000001))

start_time = timeit.default_timer()

sum_list = sum([i**2 for i in my_list])

end_time = timeit.default_timer()

print(f"纯Python列表计算时间: {end_time - start_time}")

# 使用NumPy数组计算

my_array = np.arange(1, 1000001)

start_time = timeit.default_timer()

sum_array = np.sum(my_array**2)

end_time = timeit.default_timer()

print(f"NumPy数组计算时间: {end_time - start_time}")

import numpy as np

import timeit

# 纯Python列表计算

my_list = list(range(1, 1000001))

start_time = timeit.default_timer()

sum_list = sum([i**2 for i in my_list])

end_time = timeit.default_timer()

print(f"纯Python列表计算时间: {end_time - start_time}")

# 使用NumPy数组计算

my_array = np.arange(1, 1000001)

start_time = timeit.default_timer()

sum_array = np.sum(my_array**2)

end_time = timeit.default_timer()

print(f"NumPy数组计算时间: {end_time - start_time}")

import numpy as np

import timeit

# 纯Python列表计算

my_list = list(range(1, 1000001))

start_time = timeit.default_timer()

sum_list = sum([i**2 for i in my_list])

end_time = timeit.default_timer()

print(f"纯Python列表计算时间: {end_time - start_time}")

# 使用NumPy数组计算

my_array = np.arange(1, 1000001)

start_time = timeit.default_timer()

sum_array = np.sum(my_array**2)

end_time = timeit.default_timer()

print(f"NumPy数组计算时间: {end_time - start_time}")

从运行结果可以看出,使用 NumPy 库进行数值计算的速度远远快于纯 Python 列表操作。

五、总结

通过合理选择数据结构、优化算法与代码逻辑以及充分利用 Python 的内置函数和第三方库,开发者能够显著提升 Python 代码的性能。在实际编程中,应根据具体的应用场景和需求,灵活运用这些技巧,编写出高效、健壮的 Python 代码。同时,随着 Python 语言的不断发展和优化,新的性能提升方法也将不断涌现,开发者需要持续关注和学习,以适应不断变化的编程环境。

Python代码性能优化

图注:Python 代码性能优化流程示意图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值