Python统计操作次数代码问题排查:我的实现哪里出错了?
问题分析与解决
核心问题
你的count_operations只能统计Python字节码层面的算术操作,但numpy.linalg.solve是C语言实现的底层函数,它的运算逻辑不会生成Python字节码。dis.get_instructions(solve_system)只能看到solve_system本身的Python字节码(比如变量赋值、函数调用、返回值),完全触不到numpy内部的运算,自然得不到预期结果。
另外代码还有个基础错误:没导入numpy模块,运行会报NameError: name 'np' is not defined,需要补充import numpy as np。
具体原因拆解
dis模块仅能解析Python函数编译后的字节码指令,比如LOAD_NAME、CALL_FUNCTION这类,无法深入到C扩展实现的逻辑中。solve_system的Python字节码里根本没有ADD/SUB等算术操作,它只是完成了加载函数、调用函数、返回结果的步骤,所以统计结果必然为0或远小于预期。- numpy的线性代数求解逻辑在C扩展中执行,完全脱离Python字节码流程,
dis无法获取这部分运算细节。
可行改进方向
如果想统计线性方程组求解的实际运算次数,有两种思路:
- 手动推导计算量:n阶线性方程组的LU分解等算法有固定运算量公式(如2/3n³ + O(n²)),可根据矩阵维度直接计算。
- 改用纯Python实现求解逻辑:如果一定要用
dis统计,需把求解逻辑用纯Python代码写出(比如手动实现高斯消元),这样dis才能捕获到里面的算术操作字节码。
纯Python实现示例(用于测试统计)
import dis def count_operations(f): operations = 0 for op in dis.get_instructions(f): if op.opname in ('ADD', 'SUB', 'MULT', 'DIV', 'MOD'): operations += 1 return operations def gaussian_elimination(A, b): n = len(b) # 构造增广矩阵 aug = [A[i] + [b[i]] for i in range(n)] for i in range(n): # 找主元行 max_row = max(range(i, n), key=lambda k: abs(aug[k][i])) aug[i], aug[max_row] = aug[max_row], aug[i] # 归一化主元行 pivot = aug[i][i] for j in range(i, n+1): aug[i][j] /= pivot # 消去其他行 for k in range(n): if k != i and aug[k][i] != 0: factor = aug[k][i] for j in range(i, n+1): aug[k][j] -= factor * aug[i][j] x = [row[-1] for row in aug] return x A = [[2, 3], [3, 4]] b = [8, 11] operations = count_operations(gaussian_elimination) print(f'Number of operations: {operations}')
内容的提问来源于stack exchange,提问作者mike
相关产品推荐
相关产品推荐

