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 ...
随机推荐
- 寻找jar包的好方法
好东西分享下: 下载jar包不用愁 http://maven.outofmemory.cn/
- linux 解决 gvfsd-smb-browse CPU 100%占用
原文地址:https://bugzilla.redhat.com/show_bug.cgi?id=1303300 1: sudo vim /etc/samba/smb.conf 2:定位到[globa ...
- 解决ARCGIS10.2与VS2013不兼容
在注册表中HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0增加类型为REG_SZ的InstallDir节点.Ins ...
- Django组件:用户认证组件
一丶用户认证 1.auth模块 from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其中的三个: (1).authent ...
- ajax的jquery写法和原生写法
一.ajax的简介 Ajax被认为是(Asynchronous(异步) JavaScript And Xml的缩写).现在,允许浏览器与服务器通信而无须刷新当前页面的技术都被叫做Ajax. 同步是指: ...
- css钻石旋转实现
css钻石旋转实现: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...
- Vue.js(2.x)之列表渲染(v-for/key)
1.v-for是Vue里的循环语句,与其他语言的循环大同小异.首先得有需要循环且不为空的数组,循环的关键字为in或of. 需要索引时的写法: v-for里的in可以使用of代替: 还可以使用v-for ...
- Vue.js(2.x)之计算属性
昨天看完大神的文章后,深感惭愧,硬着头皮继续看官网文档,然而这真的没是没办法,介绍的实在有些敷衍: 1).计算属性:也不说下computed是计算属性关键词,vm实例是可以像代理data一样代理com ...
- jmeter之吞吐量、吞吐率、TPS、带宽及压力测试和负载测试及其区别
一般使用单位时间内服务器处理的请求数来描述其并发处理能力.称之为吞吐率(Throughput),单位是 “req/s”.吞吐率特指Web服务器单位时间内处理的请求数另一种描述,吞吐率是,单位时间内网络 ...
- ubuntu14.04server下安装scala+sbt工具
安装sbt参考https://www.cnblogs.com/wrencai/p/3867898.html 在安装scala时 首先得安装jdk环境,最好安装最新版本以免后续安装出现不必要的麻烦 一. ...