Python实现以时间换空间的缓存替换算法


Posted in Python onFebruary 19, 2016

缓存是指可以进行高速数据交换的存储器,它先于内存与CPU交换数据,因此速度很快。缓存就是把一些数据暂时存放于某些地方,可能是内存,也有可能硬盘。

在使用Scrapy爬网站的时候,产生出来的附加产物,因为在Scrapy爬取的时候,CPU的运行时间紧迫度不高(访问频次太高容易被封禁),借此机会难得来上一下,让自己的内存解放一下。

算法原理:

通过将要缓存的数据用二进制展开,得到的二进制数据映射到缓存字段上,要检验是否已经缓存过,仅需要去查找对应的映射位置即可,如果全部匹配上,则已经缓存。

# 二进制就是个二叉树
# 如下面可以表示出来的数据有0, 1, 2, 3四个(两个树独立)

0 1
/ \ / \
0 1 0 1

因此对缓存的操作就转化为对二叉树的操作,添加和查找只要在二叉树上找到对应路径的node即可。

算法关键代码:

def _read_bit(self, data, position):
return (data >> position) & 0x1
def _write_bit(self, data, position, value):
return data | value << position

实际使用效果如何呢?

在和Python默认的 set 相比较,得出测试结果如下(存取整型,不定长字符串,定长字符串):

Please select test mode:4
Please enter test times:1000
====================================================================================================
TEST RESULT::
====================================================================================================
set() bytecache
items 1000 1000
add(s) 0.0 0.0209999084473
read(s) 0.0 0.0149998664856
hits 1000 1000
missed 0 0
size 32992 56
add(s/item) 0.0 2.09999084473e-05
read(s/item) 0.0 2.09999084473e-05
====================================================================================================
size (set / bytecache): 589.142857143
add time (bytecache / set): N/A
read time (bytecache / set): N/A
====================================================================================================
...test fixed length & int data end...
====================================================================================================
TEST RESULT::
====================================================================================================
set() bytecache
items 1000 1000
add(s) 0.00100016593933 6.1740000248
read(s) 0.0 7.21300005913
hits 999 999
missed 0 0
size 32992 56
add(s/item) 1.00016593933e-06 0.0061740000248
read(s/item) 0.0 0.0061740000248
====================================================================================================
size (set / bytecache): 589.142857143
add time (bytecache / set): 6172.97568534
read time (bytecache / set): N/A
====================================================================================================
...test mutative length & string data end...
====================================================================================================
TEST RESULT::
====================================================================================================
set() bytecache
items 1000 1000
add(s) 0.0 0.513999938965
read(s) 0.0 0.421000003815
hits 999 999
missed 0 0
size 32992 56
add(s/item) 0.0 0.000513999938965
read(s/item) 0.0 0.000513999938965
====================================================================================================
size (set / bytecache): 589.142857143
add time (bytecache / set): N/A
read time (bytecache / set): N/A
====================================================================================================
...test Fixed length(64) & string data end...

测试下来,内存消耗控制的比较好,一直在56字节,而是用 set 的内存虽然也不是很大,当相较于 ByteCache 来说,则大上很多。

但 ByteCache 的方式来缓存,最大的问题是当碰到非常大的随机数据时,消耗时间会比较惊人。如下面这种随机长度的字符串缓存测试结果:

Please select test mode:2
Please enter test times:2000
====================================================================================================
TEST RESULT::
====================================================================================================
set() bytecache
items 2000 2000
add(s) 0.00400018692017 31.3759999275
read(s) 0.0 44.251999855
hits 1999 1999
missed 0 0
size 131296 56
add(s/item) 2.00009346008e-06 0.0156879999638
read(s/item) 0.0 0.0156879999638
====================================================================================================
size (set / bytecache): 2344.57142857
add time (bytecache / set): 7843.63344856
read time (bytecache / set): N/A
====================================================================================================
...test mutative length & string data end...

在2000个数据中,添加消耗31s,查找消耗44s,而 set 接近于0,单条数据也需要16ms(均值)才能完成读/写操作。

不过,正如开头说的,在紧迫度不是很高的Scrapy中,这个时间并不会太过于窘迫,更何况在Scrapy中,一般是用来缓存哈希后的数据,这些数据的一个重要特性是定长,定长在本缓存算法中还是表现不错的,在64位长度的时候,均值才0.5ms。而与此同时倒是能在大量缓存的时候,释放出比较客观的内存。

如果有更好的缓存算法能让速度在上新台阶,也是无比期待的。。。

总结:

1. 此方法的目标是用时间换取空间,切勿在时间紧迫度高的地方使用

2. 非常适用于大量定长,且数据本身比较小的情况下使用

3. 接2,非常不建议在大量不定长的数据,而且数据本身比较大的情况下使用

以上内容是小编给大家介绍的Python实现以时间换空间的缓存替换算法,希望对大家有所帮助!

Python 相关文章推荐
Python实现动态添加类的属性或成员函数的解决方法
Jul 16 Python
解决Python 遍历字典时删除元素报异常的问题
Sep 11 Python
python实现超市扫码仪计费
May 30 Python
对TensorFlow中的variables_to_restore函数详解
Jul 30 Python
浅谈PySpark SQL 相关知识介绍
Jun 14 Python
分析运行中的 Python 进程详细解析
Jun 22 Python
对python中return与yield的区别详解
Mar 12 Python
python用Tkinter做自己的中文代码编辑器
Sep 07 Python
基于Python制作一副扑克牌过程详解
Oct 19 Python
python sleep和wait对比总结
Feb 03 Python
Python实现批量自动整理文件
Mar 16 Python
OpenCV实现常见的四种图像几何变换
Apr 01 Python
Python使用爬虫猜密码
Feb 19 #Python
使用Python简单的实现树莓派的WEB控制
Feb 18 #Python
在Ubuntu系统下安装使用Python的GUI工具wxPython
Feb 18 #Python
以一个投票程序的实例来讲解Python的Django框架使用
Feb 18 #Python
使用Python生成随机密码的示例分享
Feb 18 #Python
使用Python的urllib2模块处理url和图片的技巧两则
Feb 18 #Python
讲解Python的Scrapy爬虫框架使用代理进行采集的方法
Feb 18 #Python
You might like
用PHP 快速生成 Flash 动画的方法
2007/03/06 PHP
php笔记之:AOP的应用
2013/04/24 PHP
PHP导航下拉菜单的实现如此简单
2013/09/22 PHP
PHP获取当前所在目录位置的方法
2014/11/26 PHP
PHP中如何使用session实现保存用户登录信息
2015/10/20 PHP
jquery与google map api结合使用 控件,监听器
2010/03/04 Javascript
node.js解决获取图片真实文件类型的问题
2014/12/20 Javascript
基于Jquery+div+css实现弹出登录窗口(代码超简单)
2015/10/27 Javascript
javascript执行环境及作用域详解
2016/05/05 Javascript
基于JS实现textarea中获取动态剩余字数的方法
2016/05/25 Javascript
JavaScript中Form表单技术汇总(推荐)
2016/06/26 Javascript
js中scrollTop()方法和scroll()方法用法示例
2016/10/03 Javascript
js实现简单的手风琴效果
2017/02/27 Javascript
jQuery上传多张图片带进度条样式(DEMO)
2017/03/02 Javascript
微信小程序 滚动到某个位置添加class效果实现代码
2017/04/19 Javascript
详解Vue 普通对象数据更新与 file 对象数据更新
2017/04/26 Javascript
浅谈vue的iview列表table render函数设置DOM属性值的方法
2017/09/30 Javascript
原生JavaScript实现todolist功能
2018/03/02 Javascript
JS实现图片旋转动画效果封装与使用示例
2018/07/09 Javascript
深入分析在Python模块顶层运行的代码引起的一个Bug
2014/07/04 Python
python脚本设置系统时间的两种方法
2016/02/21 Python
浅谈插入排序算法在Python程序中的实现及简单改进
2016/05/04 Python
python-docx修改已存在的Word文档的表格的字体格式方法
2018/05/08 Python
Tornado Web Server框架编写简易Python服务器
2018/07/28 Python
深入浅析Python中list的复制及深拷贝与浅拷贝
2018/09/03 Python
Python用字典构建多级菜单功能
2019/07/11 Python
Python实现中值滤波去噪方式
2019/12/18 Python
大数据分析用java还是Python
2020/07/06 Python
香港太阳眼镜网上商店:SmartBuyGlasses香港
2016/07/22 全球购物
英国可持续奢侈品包包品牌:Elvis & Kresse
2018/08/05 全球购物
波兰快递服务:Globkurier.pl
2019/11/08 全球购物
2014年人大工作总结
2014/12/10 职场文书
2015年教师党员自我评价材料
2015/03/04 职场文书
2016年9月份红领巾广播稿
2015/12/21 职场文书
Win11运行育碧游戏总是崩溃怎么办 win11玩育碧游戏出现性能崩溃的解决办法
2022/04/06 数码科技
Win11如何设置右键单击显示所有选项?Win11右键单击显示所有选项设置教程
2022/04/08 数码科技