一、利用正则表达式
关键正则表达式
.*(关键词1|关键词2|关键词3).*
模拟业务代码
@WebServlet(name = "PatternControl", urlPatterns = {"/p"}) |
时间空间占用情况
前提
关键词共有28448个,将其编译成上述的正则表达式
CPU | 2.2GHz Intel i7四核 |
---|---|
内存 | 16GB 1600 MHz DDR3 |
时间情况(多次实验平均结果)
阶段 | 耗时(ms) |
---|---|
初始化 |
读取敏感词:38 编译正则表达式:41 |
每次匹配 | 47 |
空间情况(多次实验平均结果)
阶段 | 消耗内存(MB) |
---|---|
初始化 编译正则表达式 | 11 |
每次匹配 | 极小 |
cpu和堆运行时情况图
结论
利用正则表达式过滤敏感词效果较好
二、利用字符串暴力匹配
核心思路
循环总共关键词个数次,判断时候在待匹配字符串中 是否包含 本次循环的关键词
模拟业务代码
@WebServlet(name = "PatternControl", urlPatterns = {"/p"}) |
时间空间占用情况
时间情况(多次实验平均结果)
阶段 | 耗时(ms) |
---|---|
初始化 | 读取敏感词:38 |
每次匹配 | 10 |
空间情况(多次实验平均结果)
阶段 | 消耗内存(MB) |
---|---|
初始化 | 3 |
每次匹配 | 极小 |
结论
利用暴力匹配的效果更好
三、利用Tire树匹配
核心思路
将所有的敏感词构成一棵路径树,每个节点只有一个字符
模拟业务代码
public class TestAcWithoutFail { |
时间空间占用情况
时间情况(多次实验平均结果)
阶段 | 耗时(ms) |
---|---|
初始化 |
读取敏感词:38 构建比较树:36 |
每次匹配 | 0.01量级(执行1000遍34ms、执行10000遍130ms) |
空间情况(多次实验平均结果)
阶段 | 消耗内存(MB) |
---|---|
初始化 |
读取字符串:3 构建比较树:24 |
每次匹配 | 极小 |
结论
在该业务中和暴力匹配效果哪个好值得商榷
四、服务部署方式
主站的做法(刘乐那边的做法一样)
- 单独部署一台服务器
- 将关键词放到一张表中
- 设置定时任务每天初始化一次
我的方案
- 将关键词放到一张表中
- 设置定时任务每天初始化一次(其实感觉每天更新都挺浪费的,写个接口,表中数据改了之后,调用一下就可以)
- 多台机器上每个机器都每天读取一次数据库,解决同步的问题(或者用Tair缓存这些数据,但我感觉是不是弄麻烦了)