python字节码的运行速度和什么有关_Python 字节码优化问题

修改方案

做了个测试,基于python 2.7.3,把PyEval_EvalFrameEx这个函数里的case都改成了label,然后利用gcc的labels as values特性,将里面用到的118个opcode与对应的label构成数组:

static void *label_hash[256] = {NULL};

static int initialized = 0;

if (!initialized)

{

#include "opcodes.c"

#include "labels.c"

int i, n_opcode = sizeof(opcode_list) / sizeof(*opcode_list);

for (i = 0; i < n_opcode; i++)

label_hash[opcode_list[i]] = label_list[i];

initialized = 1;

}

然后把 switch (opcodes) 改成

void *label = label_hash[opcode];

if (label == NULL)

goto default_opcode;

goto *label;

并逐个替换每个case里的break。

编译后通过了所有的测试(除了test_gdb,这个跟未修改版一样,都是没有sys.pydebug),也就是说这个修改是正确的。

性能测试

接下来的问题是性能……这个该怎么测试呢……没有好的想法,所以随便找了两段代码:

直接loop 5kw次:

i = 50000000

while i > 0:

i -= 1

修改前运行4次:[4.858, 4.851, 4.877, 4.850],去掉最大的一次,平均4.853s

修改后运行4次:[4.558, 4.546, 4.550, 4.560],去掉最大的一次,平均4.551s

性能提升 (100% - (4.551 / 4.853)) = 6.22%

递归Fibonacci,计算第38个

def fib(n):

return n if n <= 2 else fib(n - 2) + fib(n - 1)

print fib(37)

修改前 [6.227, 6.232, 6.311, 6.241],去掉最大的一次,平均6.233s

修改后 [5.962, 5.945, 6.005, 6.037],去掉最大的一次,平均5.971s

性能提升 (100% - (5.971 / 6.233)) = 4.20%

结论

综合看来,这个小小的改动,的确可以提高5%左右的性能,不知道对各位而言意义有多大……

不过因为用到了只有GCC支持的、非C标准的特性,所以不方便移植。根据StackOverflow的这个帖子,MSVC可以在一定程度上支持,但是貌似很tricky。不知道这个在Python的发展历程中是否有人做过这样的尝试,也许官方会偏好可移植性?也许抽空可以发个帖子去问问。 根据 @方泽图 的说法(见他答案里的评论),Python 3.0+引入了这个优化。详情可以参见他的答案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值