Python标准库Difflib有坑?——两个方法快速提升数据对比效率-创新互联
一 前言
创新互联专注于企业全网营销推广、网站重做改版、红旗网站定制设计、自适应品牌网站建设、H5高端网站建设、成都做商城网站、集团公司官网建设、成都外贸网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为红旗等各大城市提供网站开发制作服务。最近在开发的数据核对方案中用到了Python标准库Difflib,本来它工作的挺符合预期,可当它遇到那个文件,仿佛遇到了克星,那文件才100行*77列的数据,经它对比,居然耗时61s。这是无法接受的,因为后续线上流量抽取比对,绝非这点量级。该怎么破?
二 重现现象
以下是使用Difflib比对那个文件,数据量是100行*77列,耗时61s,如下:
好吧,那就降低数据量到5行*77列,看看效果,耗时只有0.05s,如下:
从耗时结果上,不难发现,Difflib在这个文件的比对性能较差,而且耗时不随数据量线性增加,这是最恐怖的地方,如果继续增大数据量,耗时将会变得无法忍受。
三 优化思路
Difflib作为标准库,它的功能只是比对数据,然后生成各样结果格式。当遇到耗时严重这类问题,首先应该从自己的数据上入手,我的优化思路有两个:
第一, 过滤掉相同的行数据,降低比对数据量;
第二, 数据分片;
针对第一个思路,将文件以行分割存放到列表,然后将列表相同位置的相同数据删除掉,只剩下不同的行数据,这样做的好处很明显,一方面可以降低比对的数据量,提升效率,另外,输出的结果也更干净,不会再输出无必要的相同行数据;
针对第二个思路,将待比对的数据划分成一个个相对较小的数据块,实现快速比对,这个方法的可行性,可以从上述数据量耗时比对得出。
四 具体实现
过滤相同行优化策略,实现代码如下:
# 过滤相同行 source_length = len(source) # source为原始数据按行分割的列表 target_length = len(target) # target为目标数据按行分割的列表 min_length = source_length if source_length < target_length else target_length pos_list = [] # 标记相同行的行号,保留列头 for index in range(1, min_length): # 注意保序 if operator.eq(source[index], target[index]): pos_list.append(index) # 删除相同行数据, 注意索引漂移 source = [source[index] for index in range(source_length) if index not in pos_list] target = [target[index] for index in range(target_length) if index not in pos_list]数据分片优化策略,实现代码如下:
# 分片 max_length = source_length if source_length > target_length else target_length # 用于分片 # 分片,注意保证不能漏行 start_pos = 0 step = 10 # 分片大小,即单次比对行数,默认10行 end_pos = start_pos + step diff = difflib.HtmlDiff() # 创建htmldiff实例对象 while end_pos < max_length + step: detail_info = diff.make_file(source[start_pos: end_pos], target[start_pos: end_pos]) # 处理逻辑五 优化结果
在仅使用数据分片的优化策略的情况下,比对那个100行*77列的文件,结果显示比对耗时仅1.8s。而正如上文所述,优化前比对该文件的耗时为61s,更重要的是,因为数据分片,每片比对耗时基本稳定,即使数据量继续增大,耗时也只是线性增加,而不再是类似指数型增加。另外,如果叠加过滤数据的第一种策略,相信随着数据量的下降,耗时数据会有更好的表现。但为了更直观的比对相同数据量下优化前后的效果,所以,在此只是使用数据分片的策略。
优化后耗时结果如下:
六 其他
本文针对Python标准库Difflib比对文件时遇到的耗时严重问题,提出了两种优化策略,并经测试验证有效,即仅在数据分片策略下,同样文件的比对耗时从原先的61s降到1.8s,且耗时只是线性增加。如果有更好的方法,欢迎留言、交流。
关于python学习、分享、交流,笔者开通了微信公众号【小蟒社区】,感兴趣的朋友可以关注下,欢迎加入,建立属于我们自己的小圈子,一起学python。
另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
新闻标题:Python标准库Difflib有坑?——两个方法快速提升数据对比效率-创新互联
网址分享:http://scyanting.com/article/ccceod.html