Python 代码优化技巧(一)
Table of Contents
代码优化Part1
分享最近看到的关于代码优化的一些技巧。
if 判断的短路特性
对于and,应该把满足条件少的放在前面,这样当对于大量判断时, 满足条件少的情况直接回导致其后其他表达式不会计算从而节约时间(因为 False and True 还是 False)
import timeit
s1 = """
a = range(2000)
[i for i in a if i % 2 ==0 and i > 1900]
"""
s2 = """
a = range(2000)
[i for i in a if i > 1900 and i % 2 ==0]
"""
print timeit.timeit(stmt=s1, number=1000)
print timeit.timeit(stmt=s2, number=1000)
运行结果如下:
➜ python test6.py
0.248532056808
0.195827960968
# 可以看到s2 表达式计算更快, 因为大部分情况都不满足 i>1900, 所以这些情况下, i % 2 == 0 也没有计算,从而节约了时间
同理对于or,把满足条件多的放在前面。
import timeit
s1 = """
a = range(2000)
[i for i in a if 10 < i <20 or 1000 < i < 2000]
"""
s2 = """
a = range(2000)
[i for i in a if 1000 < i < 2000 or 10 < i <20]
"""
print timeit.timeit(stmt=s1, number=1000)
print timeit.timeit(stmt=s2, number=1000)
运行结果:
0.253124952316
0.202992200851
join 合并字符串
join 合并字符串比循环使用 + 来合并要快。
import timeit
s1 = """
a = [str(x) for x in range(2000)]
s = ''
for i in a:
s += i
"""
s2 = """
a = [str(x) for x in range(2000)]
s = ''.join(a)
"""
print timeit.timeit(stmt=s1, number=1000)
print timeit.timeit(stmt=s2, number=1000)
运行结果如下:
python test6.py
0.558945894241
0.422435998917
while 1 和 while True
在python2.x里, True 和 False 不是保留的关键字,是一个全局变量,这意味着你可以这样
>>> True = 0
>>> True
0
>>> if not True:
... print '1'
...
1
所以下面这两种情况:
import timeit
s1 = """
n = 1000000
while 1:
n -= 1
if n <= 0: break
"""
s2 = """
n = 1000000
while True:
n -= 1
if n <= 0: break
"""
print timeit.timeit(stmt=s1, number=100)
print timeit.timeit(stmt=s2, number=100)
运行结果如下:
➜ python test6.py
5.18007302284
6.84624099731
因为每次判断 while True 的时候, 先要去找到True的值。
在python3.x里, True 变成了关键字参数,所以上述两种情况就一样了。
cProfile, cStringIO 和 cPickle
使用C语言的版本写的扩展要比原生的要快。cPickle vs pickle 如下:
import timeit
s1 = """
import cPickle
import pickle
n = range(10000)
cPickle.dumps(n)
"""
s2 = """
import cPickle
import pickle
n = range(10000)
pickle.dumps(n)
"""
print timeit.timeit(stmt=s1, number=100)
print timeit.timeit(stmt=s2, number=100)
运行结果如下:
➜ python test6.py
0.182178974152
1.70917797089
合理使用生成器
区别
使用()得到的是一个generator对象,所需要的内存空间与列表的大小无关,所以效率会高一些。
import timeit
s1 = """
[i for i in range (100000)]
"""
s2 = """
(i for i in range(100000))
"""
print timeit.timeit(stmt=s1, number=1000)
print timeit.timeit(stmt=s2, number=1000)
结果:
➜ python test6.py
5.44327497482
0.923446893692
但是对于需要循环遍历的情况:使用迭代器效率反而不高,如下:
import timeit
s1 = """
ls = range(1000000)
def yield_func(ls):
for i in ls:
yield i+1
for x in yield_func(ls):
pass
"""
s2 = """
ls = range(1000000)
def not_yield_func(ls):
return [i+1 for i in ls]
for x in not_yield_func(ls):
pass
"""
print timeit.timeit(stmt=s1, number=10)
print timeit.timeit(stmt=s2, number=10)
结果如下:
➜ python test6.py
1.03186702728
1.01472687721
所以使用生成器是一个权衡的结果,对于内存、速度综合考虑的结果。
xrange
在python2.x里xrange 是纯C实现的生成器,相对于range来说,它不会一次性计算出所有值在内存中。但它的限制是只能和整型一起工作:你不能使用long或者float。
import 语句的开销
import语句有时候为了限制它们的作用范围或者节省初始化时间,被卸载函数内部,虽然python的解释器不会重复import同一个模块不会出错,但重复导入会影响部分性能。
有时候为了实现懒加载(即使用的时候再加载一个开销很大的模块),可以这么做:
email = None
def parse_email():
global email
if email is None:
import email
...
# 这样一来email模块仅会被引入一次,在parse_email()被第一次调用的时候。
参考资源:
- https://wiki.python.org/moin/PythonSpeed/PerformanceTips
- http://blog.csdn.net/zhoudaxia/article/details/23853609
- https://www.ibm.com/developerworks/cn/linux/l-cn-python-optim/
NEXT ctypes
Python 代码优化技巧(一)的更多相关文章
- python代码优化技巧
转自:http://www.douban.com/group/topic/31478102/ 这个资料库还有些不错的好文章: http://www.ibm.com/developerworks/cn/ ...
- python基础===Python 代码优化常见技巧
Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化.扩展以及文档相关的事情通常需要消耗 8 ...
- #1 Python灵活技巧
前言 Python基础系列博文已顺利结束,从这一篇开始将进入探索更加高级的Python用法,Python进阶系列文章将包含面向对象.网络编程.GUI编程.线程和进程.连接数据库等.不过在进阶之前,先来 ...
- Python 实用技巧
模块相关 导入模块时,可以通过模块的 __file__ 属性查看模块所在磁盘的路径位置,参考:关于Python包和模块的10个知识清单 Pip 安装Pip 方法一: sudo apt-get purg ...
- Python爬虫技巧
Python爬虫技巧一之设置ADSL拨号服务器代理 reference: https://zhuanlan.zhihu.com/p/25286144 爬取数据时,是不是只能每个网站每个网站的分析,有没 ...
- 一些你需要知道的Python代码技巧
被人工智能捧红的 Python 已是一种发展完善且非常多样化的语言,其中肯定有一些你尚未发现的功能.本文或许能够让你学到一些新技巧. Python 是世界上最流行.热门的编程语言之一,原因很多,比 ...
- 掌握这个Python小技巧,轻松构建cytoscape导入文件
今天小编和大家分享如何借助Python脚本轻松构建cytoscape导入文件.Cytoscape是一个非常适合展示各种相互作用关系的可视化软件. 具体来说就是可以用于蛋白互作网络的展示,miRNA与蛋 ...
- 掌握这些Python代码技巧,编程至少快一半!
被人工智能捧红的 Python 已是一种发展完善且非常多样化的语言,其中肯定有一些你尚未发现的功能.本文或许能够让你学到一些新技巧. Python 是世界上最流行.热门的编程语言之一,原因很多,比 ...
- python数据处理技巧二
python数据处理技巧二(掌控时间) 首先简单说下关于时间的介绍其中重点是时间戳的处理,时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00 ...
随机推荐
- Java并发包——线程同步和锁
Java并发包——线程同步和锁 摘要:本文主要学习了Java并发包里有关线程同步的类和锁的一些相关概念. 部分内容来自以下博客: https://www.cnblogs.com/dolphin0520 ...
- Java并发(六):并发策略
通过多次优化实例来了解选择并发策略的正确姿势 通过模拟浏览器程序的渲染页面(Page-Rendering)功能,为了方便,假设HTML页面只会包含标签文本和图片以及URL; 第一个版本:串行加载页面元 ...
- parameter与attribute的使用场合(转载自草原和大树)
Attribute 和 Parameter 的区别 (1)HttpServletRequest类有setAttribute()方法,而没有setParameter()方法 (2)当两个Web组件之间为 ...
- Teradata 认证系列 - 1. TCPP这是个啥
一看历史,好几年没发帖...正好最近在自学teradata认证(学也不一定学的完,最后也不一定去考,仅仅安慰一下不想碌碌无为的内心) 网上一搜,百度上的中文相关资料简直为0.这个不奇怪,毕竟都没什么人 ...
- js技巧-使用reduce实现更简洁的数组对象去重和数组扁平化
Array.prototype.reduce()方法介绍: 感性认识reduce累加器: const arr = [1, 2, 3, 4]; const reducer = (accumulator, ...
- js addEventListener调用传参函数
先看这段代码 function abc(key){ console.log(key); } for(let i=0;i<oInput.length;i++){ oInput[i].addEven ...
- 在wpf或winform关闭子窗口或对子窗口进行某个操作后刷新父窗口
父窗口: ///<summary> ///弹出窗口 ///</summary> ///<param name="sender"></pa ...
- ajax请求总是返回error的问题
多半是因为返回值格式的问题,在后台返回的应与前台设定的值一直,不然就会进入error,会报404服务器错误,极有可能是后台返回的数据类型不对 public void exitSystem( HttpS ...
- fancyBox高级进阶用法
最近给客户做的一个项目中,客户要求弹窗的边界与页面某个区块边界平齐,但平齐之后,弹出的窗口就不是居中的情况了,研究之后,认为需要改写fancyBox的fancybox-wrap类中的top属性才能达到 ...
- 【extjs6学习笔记】1.13 初始: 模型
Ext JS包括数据包Ext.data包括处理从服务器保存和检索数据的类. 以下是Ext JS 6数据包中的重要类: Model (Ext.data.Model) Store (Ext.data.St ...