You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python循环中如何存储多组输出以统计归并排序测试耗时

问题描述

需要实现归并排序性能测试的自动化流程,测试规则如下:

  • 统计归并排序算法的执行耗时
  • 共测试5种不同长度的随机列表:元素量从600起步,步长100,最大到1000
  • 每种列表长度下,使用10个不同的随机种子生成测试数据
  • 每个随机种子对应的测试列表,重复执行10次排序测试

现有代码已经可以输出所有单次测试的耗时数值,但无法按测试轮次对结果做统计处理(包括计算均值、极差(最大值减最小值)等指标)。尝试将不同轮次的输出存入独立列表时,不知道如何在嵌套循环结构中区分不同轮次的存储对象。

原有实现代码
import time, random, statistics

myseed = 0
myrange = 600

randomlist = []
random.seed(myseed)

def generate_random_list():
    for i in range(0,myrange):
        randomlist.append(random.randint(0,10000))

generate_random_list()


def mergeSort(arr):
    if len(arr) > 1:
            
        mid = len(arr)//2
        L = arr[:mid]
        R = arr[mid:]
        mergeSort(L)
        mergeSort(R)

        i = j = k = 0

        while i < len(L) and j < len(R):
            if L[i] < R[j]:
                arr[k] = L[i]
                i += 1
            else:
                arr[k] = R[j]
                j += 1
            k += 1

        while i < len(L):
            arr[k] = L[i]
            i += 1
            k += 1

        while j < len(R):
            arr[k] = R[j]
            j += 1
            k += 1

arr = randomlist
    
    
def procedure():
    starttime = time.time()
    mergeSort(arr)
    endtime = time.time()
    elapsedtime = endtime - starttime
    
    print(elapsedtime)


while myrange <= 1000:
    print(f"\n this is range {myrange}")
    
    while myseed <= 9:
        print(f"\n this is seed {myseed}")
        
        for x in range(0,10):
            procedure()
        
        myseed += 1
                
    
    myrange += 100
    myseed = 0
实现方案

原代码除了结果存储的问题,还有两个会导致测试结果失效的逻辑问题:

  • 随机列表仅在代码初始化时生成一次,切换列表长度、切换随机种子时不会生成新的测试数据
  • 排序直接在原列表上修改,同一份列表第二次执行排序时,输入已经是有序状态,测出来的耗时不具备参考价值

不需要手动创建大量独立列表存储不同轮次的结果,直接用嵌套字典按测试维度分层存储即可,三层结构刚好对应三层测试循环:第一层键为列表长度,第二层键为随机种子值,第三层存储对应条件下10次单次测试的耗时,循环执行时直接按当前遍历到的长度、种子值定位存储位置即可。

修正后的可运行代码如下:

import time
import random
import statistics

def mergeSort(arr):
    if len(arr) > 1:
        mid = len(arr)//2
        L = arr[:mid]
        R = arr[mid:]
        mergeSort(L)
        mergeSort(R)

        i = j = k = 0
        while i < len(L) and j < len(R):
            if L[i] < R[j]:
                arr[k] = L[i]
                i += 1
            else:
                arr[k] = R[j]
                j += 1
            k += 1

        while i < len(L):
            arr[k] = L[i]
            i += 1
            k += 1

        while j < len(R):
            arr[k] = R[j]
            j += 1
            k += 1

# 按 列表长度->随机种子->单次耗时 三层结构存储所有测试结果
test_result = {}

# 遍历所有测试的列表长度
for list_length in range(600, 1001, 100):
    test_result[list_length] = {}
    print(f"\n===== 测试列表长度:{list_length} =====")
    # 遍历所有随机种子
    for seed in range(10):
        test_result[list_length][seed] = []
        # 重置随机种子,生成对应长度的原始测试列表
        random.seed(seed)
        origin_list = [random.randint(0, 10000) for _ in range(list_length)]
        print(f"-- 当前随机种子:{seed}")
        # 重复执行10次排序测试
        for _ in range(10):
            # 每次测试使用原始列表的拷贝,避免修改原列表导致后续测试输入失真
            sort_input = origin_list.copy()
            # 用perf_counter统计短耗时精度比time.time()更高
            start_time = time.perf_counter()
            mergeSort(sort_input)
            elapsed = time.perf_counter() - start_time
            test_result[list_length][seed].append(elapsed)
            print(f"单次耗时:{elapsed:.6f}s")
        
        # 计算当前种子下的统计指标
        seed_costs = test_result[list_length][seed]
        seed_avg = statistics.mean(seed_costs)
        seed_range = max(seed_costs) - min(seed_costs)
        print(f"种子{seed}统计结果:平均耗时{seed_avg:.6f}s,极差{seed_range:.6f}s")
    
    # 计算当前列表长度下的整体统计指标
    all_costs = [cost for seed_res in test_result[list_length].values() for cost in seed_res]
    length_avg = statistics.mean(all_costs)
    length_range = max(all_costs) - min(all_costs)
    print(f"长度{list_length}整体统计:平均耗时{length_avg:.6f}s,极差{length_range:.6f}s")

关键改动说明:

  • 嵌套字典的存储结构不需要提前手动创建大量独立列表,循环过程中可以直接按当前遍历的维度定位存储位置,取数做统计时也可以按维度灵活筛选
  • 修复了原代码的测试逻辑漏洞,每次换种子重新生成测试列表,每次排序使用原始列表的独立拷贝,保证每次测试的输入一致
  • 替换计时函数为time.perf_counter(),短耗时场景下统计精度更高
  • 每跑完一个测试维度就自动计算均值、极差,需要新增标准差、中位数等统计指标时,直接调用statistics模块对应函数即可。

内容的提问来源于stack exchange,提问作者racoonfused

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 20:18:15