[Python3]踩坑实录-优化技巧1
选择合适的数据结构
考虑不同的应用场景,应选择不同的数据结构
比如在查找多于插入的场景中,考虑字典Dict是不是更适合;
因为在Python3中, 字典Dict 通过hash把key映射到hash table的不同位置(或者说不同的bucket中),
因此查找操作的复杂度为 O(1);而列表list对象实际是个数组,完成相同的查找需要遍历整个list,其复杂度为 O(n),
因此对成员的查找访问等操作字典要比 list 更快。集合Set 跟字典Dict比较类似,查找操作的复杂度为 O(1),因为其本质是一个建和值相同的dict,
不同点在于比较和插入的时候需要两步比较,第一步通过__hash__方法比较,不相同则写入,
如果是相同则进行第二步__eq__方法判断,如果还相同则丢弃,如果不同则写入。
这也是为什么下面的结果中set会比dict慢一点的原因。
import string
import time
import random if __name__ == '__main__':
# generate a list containing a-z, 26 characters
# 生成包含26个字母 的三种存储对象
array = [i for i in string.ascii_lowercase] # ['a', 'b', 'c', 'd', 'e', 'f'....
dictionary = dict.fromkeys(array, 1) # {'a': 1, 'b': 1, 'c': 1, 'd': 1....
bag = {i for i in string.ascii_lowercase} # {'q', 'v', 'u', 'y', 'z'... # set random seed
random.seed(666) # generate test data which contains some characters in alphabet and some special symbol
# 固定随机种子,生成10000000个随机数据, 一些事字母 一些特殊字符
test_data = random.choices([chr(i) for i in range(0, 123)], k=10000000)
count1, count2, count3 = 0, 0, 0
start = time.time() # 如果是字母 结果加一
for val in test_data:
count1 = count1 + 1 if val in array else count1 print(count1)
print("when using List, Execution Time: %.6f s." % (time.time() - start)) # 4.470003 s.
start = time.time() for val in test_data:
count2 = count2 + 1 if val in dictionary else count2 print(count2)
print("when using Dict Execution Time: %.6f s." % (time.time() - start)) # 1.020261 s.
start = time.time() for val in test_data:
count3 = count3 + 1 if val in bag else count3 print(count3)
print("when using Set Execution Time: %.6f s." % (time.time() - start)) # 1.045259 s.
对循环的优化
基本原则是减少循环的次数 和 循环内的计算量; 此外除了逻辑层面的优化之外,
还要在代码实现上下功夫。 尽量使用列表解析(list comprehension),生成器(generator),
还有map,reduce操作; 而不是全员for循环import time
import random if __name__ == '__main__': # set random seed
random.seed(666)
start = time.time() length = 1000000
# generate test data which contains some characters in alphabet and some special symbol
# 固定随机种子,生成10000000个随机数据, 一些事字母 一些特殊字符
list_exp_result = [chr(random.randint(0, 123)) for _ in range(length)] print(len(list_exp_result))
print("when using list comprehension, Execution Time: %.6f s." % (time.time() - start)) # 1.195765 s.
start = time.time() for_exp_result = list()
for _ in range(length):
for_exp_result.append(chr(random.randint(0, 123))) print(len(for_exp_result))
print("when using normal for loop, Execution Time: %.6f s." % (time.time() - start)) # 1.306519 s.
start = time.time() map_exp_result = list(map(lambda v: random.randint(0, 123), range(length)))
print(len(map_exp_result))
print("when using map task, Execution Time: %.6f s." % (time.time() - start)) # 1.153902 s.
更多详细探究,请移步[Python3]为什么map比for循环快
其他零碎小技巧
- 使用局部变量,避免"global" 关键字
- if done is not None 比语句 if done != None 更快
- 使用级联比较 "x < y < z" 而不是 "x < y and y < z"
- while 1 要比 while True 更快
- build in 函数通常较快,add(a,b) 要快于 a + b
- 复制列表时,使用:new_list = list(old_list)
[Python3]踩坑实录-优化技巧1的更多相关文章
- 后端路由项目由 gulp 改为 webpack 的踩坑实录
前言 公司有个后端路由的项目是用 gulp 作为前端自动化构建工具,最近学习了一下 webpack,深感其强大,一狠心将其改成了 webpack 构建,以下是踩坑实录. gulp 先来说说原来的架构. ...
- JAVA实用案例之文件导出(JasperReport踩坑实录)
写在最前面 想想来新公司也快五个月了,恍惚一瞬间. 翻了翻博客,因为太忙,也有将近五个多月没认真总结过了. 正好趁着今天老婆出门团建的机会,记录下最近这段时间遇到的大坑-JasperReport. 六 ...
- ffmpeg 踩坑实录 添加实时水印(二)
一.背景介绍 最近领导要求做一个视频录制的相关项目.其中,需要对视频文件进行添加 实时时间水印.于是,我想到了使用之前的ffmpeg来做. 二.ffmpeg实际操作 首先把需要添加水印的视频文件,上传 ...
- JasperReport报表导出踩坑实录
写在最前面 翻了翻博客,因为太忙,已经好久没认真总结过了. 正好趁着今天老婆出门团建的机会,记录下最近这段时间遇到的大坑-JasperReport. 六月份的时候写过一篇利用poi文件导入导出的小De ...
- HashMap踩坑实录——谁动了我的奶酪
说到HashMap,hashCode 和 equals ,想必绝大多数人都不会陌生,然而你真的了解这它们的机制么?本文将通过一个简单的Demo还原我自己前不久在 HashMap 上导致的线上问题,看看 ...
- (最新)VS2015安装以及卸载过程——踩坑实录
前言 Visual Studio (简称VS)是微软公司旗下最重要的软件集成开发工具产品.是目前最流行的 Windows 平台应用程序开发环境,也是无数人学习编程的入门软件之一.Visual Stud ...
- ffmpeg 踩坑实录 安装与视频切片(一)
这段时间一直在做一个关于视频处理的项目.其中有一块需要切片相关功能.于是采用了ffmpeg来完成相关需求. 第一,ffmpeg的安装. 首先下载官方包,我这里用的是ffmpeg-release-64b ...
- ubuntu搭建开发环境踩坑实录
谨以此文,记录和ubuntu系统不死不休的搏斗过程,后续待补. 1.双系统安装,windows采用uefi模式安装(优启通可制作uefi的win10安装盘),ubuntu不要划分boot区,而应该划分 ...
- H5 video踩坑实录
前段时间公司APP做了一个APP论坛会议,嵌入了h5播放器.我以为很简单,没想到,这正是我踩进泥潭的开始... (想要吸取经验的小伙伴可以慢慢往下看,想要解决方案的直接看最后!) 一.一开始我以为直接 ...
随机推荐
- 《C程序设计语言》 练习2-1
问题描述 编写一个程序以确定分别由signed及unsigned限定的char.short.int及long类型变量的取值范围.采用打印标准头文件中的相应值以及直接计算两种方式实现 Write a p ...
- CC2530ADC转换
一.ADC简介 ADC支持 14 位的模拟数字转换,具有多达12 位的 ENOB(有效数字位).它包括一个模拟多路转换器,具有多达8 个各自可配置的通道,以及一个参考电压发生器.转换结果通过DMA写入 ...
- SQL语言概况(4.1)
SQL语言概况(4.1) 目录 SQL语言概况(4.1) 4.1 SQL语言概况 4.1.1 历史及标准简介 4.1.2 SQL语言定义及特点 4.1.3 使用说明 参考资料: 数据库原理及设计(第3 ...
- Linux内核驱动学习(八)GPIO驱动模拟输出PWM
文章目录 前言 原理图 IO模拟输出PWM 设备树 驱动端 调试信息 实验结果 附录 前言 上一篇的学习中介绍了如何在用户空间直接操作GPIO,并写了一个脚本可以产生PWM.本篇的学习会将写一个驱动操 ...
- 从卷积拆分和分组的角度看CNN模型的演化
博客:博客园 | CSDN | blog 写在前面 如题,这篇文章将尝试从卷积拆分的角度看一看各种经典CNN backbone网络module是如何演进的,为了视角的统一,仅分析单条路径上的卷积形式. ...
- JS理论:编码习惯
1.声明变量,你只会var吗?那你真的是JS小鲜肉 如果要声明3个变量,你要var 三下吗? 不用: let [a,b,c] = ['name',18,'ddd'] console.log(a,b,c ...
- PC端软件配置
一,cmder软件安装 二,Snipaste软件安装 三,vwmare虚拟机安装 四,sublime安装 五,notepad++安装 六,Python环境 anaconda navigator安装 七 ...
- mysql小白系列_09 mysql性能优化关键点
一 服务器参数调优,有哪些关键点? 1. 应用访问优化 优化方法 性能提升效果 优化成本 说明 减少数据访问能不访问就不访问-减少磁盘IO 1~1000 低 缓存服务器缓存mysql数据,Redis. ...
- mysql小白系列_08 zabbix添加自定义监控项items和触发器
监控mysql存活 1.配置agent自定义参数 vi /usr/local/zabbix/etc/zabbix_agentd.conf Include=/usr/local/zabbix/etc/z ...
- 如何在HTML5中使用SVG
复制而来---原地址http://www.php100.com/html/webkaifa/HTML5/2012/0731/10776.html SVG 即 Scalable Vector Graph ...