前言
首先说一下需求,由于公司项目中有一份日志是从solr中查询出来,其中有一个ip字段,需要在页面展示为ip对应的国家和省份。数据库中存在一份地域库数据(即各个ip网段对应的国家省份城市等信息),地域库数据一共42万条,也就是solr中查询出来的数据每一条数据中的ip要在42万个IP网段中找到他所在的位置。虽然数据并不多,但是如果每条数据去找地域得话会严重影响耗时。如果单条耗时1毫秒,一万条数据耗时就是10000毫秒,可见如果数据量大的话影响是非常大的。所以想到了利用分桶来进行查找。原理是将42万数据中,将每个ip网段的开始段转为数字,然后按照这个数字分桶。分为100个桶即每个桶平均有420000/100 = 4200条数据。每个桶中的数字按照从小到大的顺序排序,即每个桶中最小的数据-1便是前一个桶的结尾。然后在每条数据的ip查找网段时同样将它转为数字即可得到该数字应该在哪个桶,然后遍历使用二分法找到值在该桶中的位置。这样的话效率便会快了很多。
正文
1. 原理
如果不理解二分法的话,可以先看这篇文章学习。这里讲一下桶排序算法,桶排序是一种排序算法,它工作的原理是将数组分到有限数量的桶中,每个桶分别排序(这里每个桶排序也可能运用到别的排序算法,例如插入排序)。
2.代码
1 | /** |
3.测试结果
1 | Random random = new Random(); |
如上,模拟了一万个ip测试,测试结果部分截图:
最终应用到项目中,使用二分法查找方式,由于数据是以每页100条分页展示,单次查询100条时该功能几乎不耗时。