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多线程编程中的join函数使用心得
Sep 02 Python
Python编程之gui程序实现简单文件浏览器代码
Dec 08 Python
详解PyTorch批训练及优化器比较
Apr 28 Python
python实现简单淘宝秒杀功能
May 03 Python
使用PM2+nginx部署python项目的方法示例
Nov 07 Python
基于Python对数据shape的常见操作详解
Dec 25 Python
python实现对输入的密文加密
Mar 20 Python
python celery分布式任务队列的使用详解
Jul 08 Python
Python中*args和**kwargs的区别详解
Sep 17 Python
python循环嵌套的多种使用方法解析
Nov 29 Python
后端开发使用pycharm的技巧(推荐)
Mar 27 Python
Python Opencv图像处理基本操作代码详解
Aug 31 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去掉从word直接粘贴过来的没有用格式的函数
2012/10/29 PHP
php版本的cron定时任务执行器使用实例
2014/08/19 PHP
php设计模式之备忘模式分析【星际争霸游戏案例】
2020/03/24 PHP
javascript数组操作(创建、元素删除、数组的拷贝)
2014/04/07 Javascript
jquery动态添加删除(tr/td)
2015/02/09 Javascript
简单谈谈javascript中this的隐式绑定
2016/02/22 Javascript
js组件SlotMachine实现图片切换效果制作抽奖系统
2016/04/17 Javascript
Bootstrap布局之栅格系统学习笔记
2017/05/04 Javascript
jQuery实现的自定义轮播图功能详解
2018/12/28 jQuery
javascript实现简易聊天室
2019/07/12 Javascript
javascript中可能用得到的全部的排序算法
2020/03/05 Javascript
[02:05]2014DOTA2西雅图邀请赛 专访啸天mik夫妻档
2014/07/08 DOTA
[43:53]OG vs EG 2019国际邀请赛淘汰赛 胜者组 BO3 第三场 8.22
2019/09/05 DOTA
教你安装python Django(图文)
2013/11/04 Python
Python的几个高级语法概念浅析(lambda表达式闭包装饰器)
2016/05/28 Python
Python数据结构与算法之二叉树结构定义与遍历方法详解
2017/12/12 Python
python打包压缩、读取指定目录下的指定类型文件
2018/04/12 Python
python内置数据类型之列表操作
2018/11/12 Python
Python socket实现多对多全双工通信的方法
2019/02/13 Python
Python3简单实现串口通信的方法
2019/06/12 Python
Python实现括号匹配方法详解
2020/02/10 Python
matplotlib 对坐标的控制,加图例注释的操作
2020/04/17 Python
python使用dlib进行人脸检测和关键点的示例
2020/12/05 Python
世界排名第一的万圣节服装店:Spirit Halloween
2018/10/16 全球购物
阿联酋航空丹麦官方网站:Emirates DK
2019/08/25 全球购物
幼儿园中秋节活动方案2013
2014/01/29 职场文书
实习会计求职自荐信范文
2014/03/10 职场文书
决心书标准格式
2014/03/11 职场文书
就业意向书
2014/07/29 职场文书
2014年团支部年度工作总结
2014/12/24 职场文书
餐饮食品安全责任书
2015/01/29 职场文书
后勤个人工作总结
2015/02/28 职场文书
小学开学典礼新闻稿
2015/07/17 职场文书
2016国庆节活动宣传语
2015/11/25 职场文书
Go语言使用select{}阻塞main函数介绍
2021/04/25 Golang
pandas求平均数和中位数的方法实例
2021/08/04 Python