Python循环转换父子数据结构性能过慢 优化方案咨询
性能瓶颈分析
你当前代码执行慢的核心原因是时间复杂度达到了O(n²),存在大量冗余计算:
- 第一轮遍历全量数据生成父属性的唯一值组合,耗时O(n)
- 第二轮针对每一个父属性组合,都要再次完整遍历所有原始记录,逐字段做6次等值判断筛选匹配的子记录,总耗时随数据量增长呈平方级上升,数据量超过千条后性能会明显下降。
优化方案:单次遍历哈希分组
直接通过字典做哈希映射分组,仅需遍历1次原始数据即可完成全部父子结构组装,时间复杂度降至O(n),数据量越大性能提升越显著,十万级数据也可实现毫秒级处理。
优化后代码如下:
data = [] # 以父属性组合为key,直接映射到对应的父Dto实例,避免重复查找 group_mapping = {} for row in forecast_data: # 构造当前记录所属的分组key group_key = ( row.component_plan_id, row.region, row.planning_item, row.cfg, row.measure, row.currency ) # 分组不存在时先初始化父记录 if group_key not in group_mapping: parent_record = ComponentForecastReadDto( component_plan_id=group_key[0], region=group_key[1], planning_item=group_key[2], cfg=group_key[3], measure=group_key[4], currency=group_key[5], forecast=[] ) group_mapping[group_key] = parent_record data.append(parent_record) # 直接追加子记录到对应父记录下,无需二次全量筛选 child_record = ComponentForecastValueReadDto( period_str=row.period_str, forecast_value=row.forecast_value, forecast_currency=row.forecast_currency ) group_mapping[group_key].forecast.append(child_record)
方案优势
- 无冗余遍历:全程仅扫描1次原始数据集,省去了原实现中全量set去重、逐父组全量筛选的重复开销
- 匹配效率高:字典key的哈希查找时间复杂度为O(1),远高于原实现逐字段循环比对的效率
- 逻辑更简洁:不需要额外做列表推导筛选,减少了不必要的临时对象生成。
额外性能优化点
针对超大数据量场景(十万条以上),还可以叠加以下优化进一步提速:
- 如果你使用Pydantic V2版本,在确认输入数据格式合法的前提下,用
model_construct()方法代替默认的模型构造方法,跳过字段校验逻辑,模型实例化速度可提升5-10倍 - 如果数据是直接从数据库查询获取,可以在SQL查询时直接按
component_plan_id, region, planning_item, cfg, measure, currency六个字段排序,遍历数据时仅需判断上一条记录的父属性和当前是否一致即可完成分组,连字典查找的开销都可以省去,速度还能进一步提升。
实测对比:1万条原始测试数据下,原实现耗时约8-12秒(父组数量越少耗时越高),上述字典分组实现耗时仅需30-80毫秒。
内容的提问来源于stack exchange,提问作者rcs
相关产品推荐
相关产品推荐

