项目组里因为需要,现要开发一个数据过滤软件,针对文本文件 (txt 文件 ) ,文本文件里的数据是 11 位的手机号码,数据约有四千万行,进行数据过滤 ( 重复号码过滤,位数非 11 位的进行过滤 ) 尽量脱离数据库。而且要提速,太慢了客户不满意的。
显然在内存里过滤数据是最快的,可是显然对于 2G 内存的本来说,可分配给 JAVA HAEP 的大小是容不下这么多数据的。那怎么办呢?
索引机制:
首先的想到的是通过 Lucene 索引机制,循环判断目标文件里是否已经存在要写入的号码,若不存在,则写入文件。
思路很清晰,但效率不高,主要是索引的速度不高,三十万的数据约要十几分钟,这太慢了。四千万的数据两个小时也跑不出来。
分割文件:
4000 万的数据文件约 500M ,一个文件太大,那可以把它分割成小文件,这里我采用的是安手机号的号段进行分割,比如把以 135 开头的手机号码读入一个文件,把 136 的开头的读入另一个文件 … 这样实际情况下是行的通的,可是如果理想的情况下是不通的,因为如果文本文件里手机号码 90% 都是 135*** 那分割后的文件 135 的还是太大了,不过可以实行循环分割,把第一次分割后的文件再次分割(取四位号码分割),如果文件还大,循环分割 …
经测试:
* 371M 的文件(3000万的数据) 过滤数据耗时: 99844毫秒
* 520M 的文件(4200万的数据) 过滤数据耗时: 369359毫秒
6 分钟可以搞定 4000 万的数据,从这个耗时看,效率有了很大的提升。基本可以满足用户的需要了。
那是不是可以更快呢?
分割法 ( 内存机制 )
第一步 :循环读取文件一遍,取出所有数据的前三位,即号段存入 List 中 ( 要滤重 )
第二步: 遍历 List 分别取出号段值 value ,再分别读取文件把数据是以 value 开头数据读入到 Set 中,当读文件结束时,写 Set 中的数据写入目标文件。
经测试:
* 371M 的文件( 3000 万的数据) 过滤数据耗时 : 70672 毫秒
* 520M 的文件( 4200 万的数据) 过滤数据耗时 : 159016 毫秒
2 多分钟可以搞定 4000 万的数据,从这个耗时看,效率有了很大的提升。已经可以满足用户的需要了。
那是不是还可以更快呢?