Python代码运行耗时检测与列表分段遍历实现方案咨询
def foo(a): for i in range(len(a)): do something return a def main(): while len(a) > 1: n = int(a[0]) print(foo((a[:n+1]))) a = a[n+1:]
问题1:如何计算代码运行耗时,定位效率低下的部分
- 粗粒度整体耗时统计:用Python内置的
time.perf_counter(),精度高于time.time(),适合统计代码段运行时间,用法示例:import time start = time.perf_counter() main() # 要运行的目标代码 end = time.perf_counter() print(f"总运行耗时:{end - start:.4f}秒") - 函数级性能定位:用标准库自带的
cProfile,可以统计每个函数的调用次数、累计耗时、单次调用耗时,直接在命令行执行即可:
输出结果会按累计耗时排序,很容易找到占用时间最多的函数。python -m cProfile -s cumulative your_script_name.py - 行级细粒度定位:如果需要定位到具体哪行代码慢,可以用第三方库
line_profiler,先给要分析的函数加@profile装饰器,再运行命令就能看到函数内每一行的运行耗时、占比:kernprof -l -v your_script_name.py
提示:你当前贴的foo函数里,循环第一次执行就会return,如果是占位的do something逻辑没写全,实际场景下如果这块是计算密集操作,大概率是性能瓶颈
问题2:切片不是唯一实现方式,还有几种更灵活、甚至性能更好的方案
- 方案1:索引偏移访问(最优,零额外开销)
不需要生成新的切片列表,直接维护遍历的起始索引,把起始、结束位置传给foo函数,直接操作原列表的对应索引范围,完全避免切片的拷贝开销,大列表场景下性能优势非常明显,改造示例:def foo(a, start, end): for i in range(start, end): # 原有逻辑不变,用a[i]访问元素即可 pass return a[start:end] # 仅需要返回对应段时才切片,不需要可以省略 def main(a): start = 0 while start < len(a) - 1: n = int(a[start]) end = start + n + 1 print(foo(a, start, end)) start = end - 方案2:迭代器遍历
把列表转成迭代器,按需求逐个取元素,不需要手动维护索引,也不会生成额外的切片副本:def main(a): iter_a = iter(a) while True: try: n = int(next(iter_a)) segment = [n] + [next(iter_a) for _ in range(n)] print(foo(segment)) except StopIteration: break - 方案3:memoryview(仅适用于字节类序列)
如果操作的是bytes、bytearray这类二进制序列,可以用memoryview实现零拷贝的子序列访问,不需要像切片一样生成新的字节对象,性能更高。
内容的提问来源于stack exchange,提问作者lunalilac
相关产品推荐
相关产品推荐

