提升python运行效率_如何让python运行速度提高3倍

【勘误:原文“30倍”效果实为代码笔误,感谢各位知友指正。这个错误确实很搞笑哈哈哈哈,以后一定注意。三倍的效果虽然不那么令人满意,不过起码在竞赛或是很需要大量I/O的项目中还是能看到明显的作用。】

随着机器学习领域的研究越来越火热,python的人气也水涨船高。上个月,python甚至第一次超过Java成为热门编程语言第一位。但有一个领域,python却不被看好,那就是编程竞赛(Competitive Programming)。

运行速度是python常常被诟病的最大缺点。然而,作为一门设计精美的语言,小小的优化就可以让代码运行速度提高数十倍。上周,一道codeforces A类题困扰了我两个小时。我非常确定我的算法已经是最优解,但是因为题目涉及到10^5量级的读写,那只有可能是python的速度是程序的瓶颈。经过一番research,我发现了一个可以让python提速3倍的方法。

import timeit

timeit.timeit()

mycode1 = '''a = [0]*200000for i in a:print(str(i), end=' ')'''

mycode2 = '''a = [0]*200000print(' '.join(str(x) for x in a))'''

print(timeit.timeit(stmt = mycode2, number = 10))

Mycode1是第一次TLE(Time Limit Exceeded)时运行的代码,运行时间为2.661秒。而第二段代码print出完全一样的东西只需要0.943秒,刚刚好进入1s的时间要求。

不难看出,第二段代码和第一段的区别在于使用了列表推导式(List Comprehension)。根据这个在Stack Overflow上的回答,使用列表推导式,python的解释器只需要查找一次 print() method,而在使用第一种方法的时候,解释器需要在每次执行循环时都要都查找一遍print函数对应的代码。

且慢,故事到这还没完。有没有什么方法可以让str()函数也只用被查找一遍?答案是有的。根据这一篇python.org上的文章,在使用隐循环(Implied Loop)如map的时候,map调用的函数也只会被查找一遍。

mycode3 = '''

a = [0]*20000

print(' '.join( i for i in map(str, a)))

使用mycode3的代码,运行时间仅为0.77秒。

最后,总结一下第二篇文章作者的几个建议:- Rule number one:only optimize when there is a proven speed bottleneck. Only optimize the innermost loop.

- Use intrinsic operations. An implied loop in map() is faster than an explicit for loop; a while loop with an explicit loop counter is even slower.

- Avoid calling functions written in Python in your inner loop. This includes lambdas. In-lining the inner loop can save a lot of time.

- Local variables are faster than globals; if you use a global constant in a loop, copy it to a local variable before the loop. And in Python, function names (global or built-in) are also global constants!最重要的法则:只有当出现了运行速度瓶颈的时候才选择优化,并且只优化最里层循环;

使用python的内置函数,比如用map而不是循环;while循环比for需要更多的时间;

尽量避免在最内层的循环内调用函数;

局部变量要比全局变量更省时;如果要在最内层函数使用全局变量,可以在循环内复制一份变量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值