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 ...
随机推荐
- Ashx增删改查_动软
1.首先展示列表 ashx 讲究的是个替换 这些就是属于ashx麻烦的地方 public void ProcessRequest(HttpContext context) { context.Resp ...
- Java基础反射-调用类
Student类 package com.test.wang; import java.lang.reflect.Constructor; import java.lang.reflect.Field ...
- 常用的Homebrew命令
一些常用的Homebrew命令: 更新:brew update 安装包信息检索:brew info 安装包搜索:brew search foo 安装包列表:brew list 过时信息:brew ou ...
- PHP函数:method_exists和function_exists
method_exists 检查类的方法是否存在 bool method_exists ( mixed $object , string $method_name ) 检查类的方法是否存在于指定的ob ...
- C#中split的方法汇总
字符串的处理往往离不开split方法,下面介绍几种split的用法: 1.对单个字符进行分割(注意这里是字符,不是字符串,故只能用单引号‘’) string s=abcdeabcdeabcde; st ...
- 怎样在github里面写个人主页
1 登录你的账号 打开
- UOJ#130 【NOI2015】荷马史诗 K叉哈夫曼树
[NOI2015]荷马史诗 链接:http://uoj.ac/problem/130 因为不能有前缀关系,所以单词均为叶子节点,就是K叉哈夫曼树.第一问直接求解,第二问即第二关键字为树的高度. #in ...
- Python 随笔之Redis
Python学习记录 ——redis 2018-03-07 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从 ...
- Android(java)学习笔记91:Eclipse中代码提示去掉@override,不然就报错!
1. Eclipse中提示去掉@Override 把项目下载下来后有@Override的注释的方法会报错,如果把@Override去掉就不报错了.经过查阅后发现:@override注释在jdk1.5环 ...
- 实现带查询功能的ComboBox控件
实现效果: 知识运用: ComboBox控件的AutoCompleteMode属性 public AutoCompleteMode AutoCompleteMode{get;set;} //属性值为枚 ...