编程学习网 > 编程语言 > Python > Python代码优化:3个被忽视的细节,让运行速度飞起来
2026
09-22

Python代码优化:3个被忽视的细节,让运行速度飞起来


Python的人经常盯着大O符号看。他们花时间选对数据结构,用上生成器,避开嵌套循环。这些做法没错。可代码跑起来还是慢,尤其当数据量上去以后。问题往往藏在更细的地方。下面说三个点,每个都能让执行时间掉一截。

细节一 · 局部变量比全局变量快       

很多人知道这条规则,但没用到点子上。看一段代码。       

import time  SIZE = 10000000  def use_global():     total = 0     for i in range(SIZE):         total += i     return total  def use_local():     total = 0     r = range     s = SIZE     for i in r(s):         total += i     return total  start = time.perf_counter() use_global() print(time.perf_counter() - start)  start = time.perf_counter() use_local() print(time.perf_counter() - start)

跑一下会发现第二个函数快15%左右。原因不复杂。Python在函数内部访问局部变量用的是数组下标,访问全局变量要查字典。rangeSIZE在第二个函数里变成了局部名字,每次循环少一次字典查找。一千万次循环,省下的时间肉眼可见。       

更隐蔽的地方在循环内部反复调用全局函数。比如你写math.sqrt(x),每次都要先找math这个全局名字,再找sqrt属性。改成from math import sqrt,然后在函数开头写sqrt_local = sqrt,循环里用sqrt_local速度能再提一截。这个做法不改变逻辑,只换名字的查找路径。       

细节二 · 字符串拼接用 join       

但知道为什么的人不多。先看错误示范。       

def bad_concat(n):     s = ''     for i in range(n):         s += str(i)     return s

字符串在Python里不可变。每次s += str(i)都创建一个新字符串,把旧内容复制过去。n等于十万时,内存分配和复制次数是平方级的。改成列表收集再join      

def good_concat(n):     parts = []     for i in range(n):         parts.append(str(i))     return ''.join(parts)

join只分配一次内存,把所有片段按顺序填进去。十万次拼接,bad_concat要几秒,good_concat几十毫秒。差别不在算法,在内存操作次数。

有人会说f-string不是更快吗?f-string适合格式化少量变量。循环里拼大量字符串,join还是首选。如果拼接的片段类型固定,可以预先算好每个片段长度,用bytearray或者直接写文件。但多数场景下join足够。       

细节三 · __slots__ 减少实例内存       

这个对速度的影响是间接的,但效果明显。看一个普通类。       

class Point:     def __init__(self, x, y):         self.x = x         self.y = y  p = Point(1, 2) print(p.__dict__)

每个实例有一个字典存属性。字典方便,能动态加属性。代价是内存占用大,属性访问要查字典。如果类里属性固定,加一行__slots__ = ('x', 'y')       

class Point:     __slots__ = ('x', 'y')     def __init__(self, x, y):         self.x = x         self.y = y  p = Point(1, 2) # p.__dict__ 会报错,没有字典了

实例不再有字典,属性存在固定偏移的位置。访问p.x变成直接取内存地址的值,比查字典快。创建一百万个Point实例,内存能省一半以上。内存省了,CPU缓存命中率上去,整体循环处理这些对象的速度跟着涨。实测在属性读写密集的循环里,用__slots__能快20%30%      

注意__slots__不是万能。继承时要小心,子类如果没定义__slots__,还是会生成字典。另外不能动态加属性,代码里如果有p.z = 3会直接报错。适合数据类、几何点、配置项这种字段固定的场景。       

这三个细节都不改代码逻辑。局部变量、join拼接、__slots__,每一个都能单独用。合在一起,一个处理百万级数据的脚本,运行时间可能从十秒掉到三秒。优化不是玄学,是搞清楚解释器在背后做了什么。你少让它干一次活,它就快一次。    

以上就是“Python代码优化:3个被忽视的细节,让运行速度飞起来的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。   

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取