已合并
【bugfix】修复目前比对DataFrame赋值导致内存占用过高程序崩溃问题 #260
【bugfix】修复目前比对DataFrame赋值导致内存占用过高程序崩溃问题 #260
已合并
louyujing创建于 1月8日
共 1 个文件变更+27-10
@@ -115,13 +115,14 @@ class ApiIndicatorCalculator:
115 self.add_algorithm(checker())115 self.add_algorithm(checker())
116 116 
117 117 
118-def calculate_excel_result_df(result_df, mode):118+def calculate_excel_result_df(result_df, mode, chunk_size=1000):
119 """119 """
120 仅适用于excel比对场景,得到表格每行数据的精度比对指标(pass/warning/error)120 仅适用于excel比对场景,得到表格每行数据的精度比对指标(pass/warning/error)
121 121 
122 Args:122 Args:
123 result_df: DataFrame数据结构,即转换成excel前的表单结构123 result_df: DataFrame数据结构,即转换成excel前的表单结构
124 mode: 比对模式,分为 tensor 模式、统计量模式和 md5 模式124 mode: 比对模式,分为 tensor 模式、统计量模式和 md5 模式
125+ chunk_size: 分块赋值参数,默认1000,把 result 分成小块,逐块赋值给 result_df,这样每次只占用小块内存,避免内存峰值过高
125 """126 """
126 result_dict = divide_result_df(result_df)127 result_dict = divide_result_df(result_df)
127 calculator = ApiIndicatorCalculator(mode)128 calculator = ApiIndicatorCalculator(mode)
@@ -130,15 +131,31 @@ def calculate_excel_result_df(result_df, mode):
130 calculator.calculate(data_lists)131 calculator.calculate(data_lists)
131 calculated_result_lists.extend(data_lists)132 calculated_result_lists.extend(data_lists)
132 133 
133- # 将列表中的列表元素转换为str,避免list转换为ndarray报错134+ head = CompareConst.HEAD_OF_COMPARE_MODE.get(mode)
134- # 可以使用一行列表推导式实现,但会被codecheck拦截(推导式和生成器表达式仅用于简单的逻辑表达)135+ if not head:
135- result = []136+ logger.error(f'Unable to obtain header based on compare mode: {mode}')
136- for sublist in calculated_result_lists:137+ raise RuntimeError()
137- processed_sublist = []138+ # 配置列映射关系:[(result_df的目标列名, result子列表的列索引)]
138- for item in sublist:139+ try:
139- processed_sublist.append(json.dumps(item)) if isinstance(item, list) else processed_sublist.append(item)140+ cols_mapping = [
140- result.append(processed_sublist)141+ (CompareConst.RESULT, head.index(CompareConst.RESULT)),
141- result_df[:] = result142+ (CompareConst.ERROR_MESSAGE, head.index(CompareConst.ERROR_MESSAGE))
143+ ]
144+ except ValueError as e:
145+ logger.error(f'The {CompareConst.RESULT} or {CompareConst.ERROR_MESSAGE} does not exist in the header: {e}')
146+ raise e
147+ 
148+ total_rows = len(calculated_result_lists)
149+ 
150+ # 分块逐批赋值,降低内存瞬时峰值
151+ for i in range(0, total_rows, chunk_size):
152+ end_idx = min(i + chunk_size, total_rows)
153+ current_result_chunk = calculated_result_lists[i:end_idx]
154+ 
155+ for df_col_name, result_col_idx in cols_mapping:
156+ col_data = [sublist[result_col_idx] for sublist in current_result_chunk]
157+ df_col_idx = result_df.columns.get_loc(df_col_name)
158+ result_df.iloc[i:end_idx, df_col_idx] = col_data
142 159 
143 160 
144def calculate_result(result, mode):161def calculate_result(result, mode):