Python测试排序算法执行时间部分结果返回0值问题咨询
问题产生原因
你遇到的随机出现0耗时的问题,来自两个核心代码缺陷,和打印语句加空格没有本质关联:
- 测试数据被所有算法共享,没有做独立隔离
你代码中写的atibtS_rand = rand_list、oaS_rand = rand_list这类写法,并没有创建新的列表,只是给原始的rand_list对象绑定了新的别名。第一个被执行的排序算法会直接原地修改这个共享列表,后续所有排序算法拿到的都是已经排好序的数据集。
插入排序处理完全有序列表的时间复杂度是O(n),900个元素的有序列表执行速度极快;而你修改打印语句加空格的操作,本质上改变了Python字节码的排布和执行时序,会微小改变各函数的调用耗时、甚至改变共享列表被修改的先后顺序,因此会随机出现1-3个算法因为拿到的是有序列表、耗时过短测出0值的情况。 - 使用
time.time()做短耗时任务计时的精度严重不足time.time()是用来获取系统当前墙钟时间的接口,并非为性能计时设计:Windows系统下它的默认计时精度仅为15毫秒左右,即便在Linux/macOS系统下精度更高,也容易受系统时间调整、时钟跳变的干扰。只要被测代码的实际耗时低于计时接口的最小分辨率,两次时间做差就会得到0.0,完全无法反映真实运行时长。 - 额外的代码笔误会放大测试误差:比如你定义的测试函数名为
other_algorithm,调用时写成了other_algorithm_(多了末尾下划线),这类笔误会导致部分函数根本没有正确执行,自然也测不出有效耗时。
可靠的排序算法计时方案
要彻底避免这类问题,需要从「测试数据隔离」和「高精度计时」两个维度修改代码:
- 所有测试用例必须使用独立的数据副本
每次运行单个排序算法前,都通过切片test_list = BASE_LIST[:]或者test_list = list(BASE_LIST)创建一份全新的未排序列表副本,绝对不允许多个算法共享同一个列表对象,避免前序测试修改数据影响后续结果。 - 使用专门的高精度计时工具
优先使用Python标准库自带的timeit模块做性能测试,它会自动选择系统上精度最高的计时器,默认关闭测试期间的垃圾回收,支持多次运行取平均消除系统调度、CPU缓存波动带来的偶然误差,是短代码片段计时的最优选择。
参考实现代码如下:import random import timeit # 固定随机种子保证测试结果可复现 random.seed(72) # 生成基础测试数据集 BASE_LIST = random.sample(range(1, 50000), 900) def measure_sort_time(sort_func, repeat_times=100): # 每次运行都生成独立的未排序副本,避免数据污染 test_runner = lambda: sort_func(list(BASE_LIST)) # 重复运行repeat_times次,返回单次运行的平均耗时 total_cost = timeit.timeit(test_runner, number=repeat_times) return total_cost / repeat_times # 调用示例:替换成你自己实现的排序函数即可 execution_t_SelS = measure_sort_time(selection_sort) execution_t_IS = measure_sort_time(insertion_sort) execution_t_SS = measure_sort_time(shell_sort) execution_t_QS = measure_sort_time(quick_sort_v1) execution_t_QS2 = measure_sort_time(quick_sort_v2) execution_t_QIHS = measure_sort_time(quick_insertion_hybrid_sort) execution_t_MS = measure_sort_time(merge_sort) execution_t_RS = measure_sort_time(radix_sort)
如果你不想用timeit做封装,至少也要替换计时接口为time.perf_counter()——这是Python专门提供的高性能计数器,分辨率远高于time.time(),且不受系统时钟调整的影响,手动计时的参考写法如下:
import time # 测试插入排序示例 test_list = BASE_LIST[:] # 必须先创建独立副本 t_start = time.perf_counter() insertion_sort(test_list) execution_t_IS = time.perf_counter() - t_start
额外测试建议
- 不要仅测试固定长度的随机乱序列表,建议补充完全有序、完全逆序、大量重复元素、不同数据长度的测试用例,才能全面对比不同排序算法的性能特性。
- 对于本身耗时极短的算法,一定要多次运行取平均结果,避免单次运行的系统波动影响结论。
- 测试前确认排序函数的行为:是原地修改输入列表,还是返回新的排序列表,避免出现函数执行了但没有触发实际排序逻辑的无效测试。
内容的提问来源于stack exchange,提问作者Tesla_Republic
相关产品推荐
相关产品推荐

