forin 循环
/**
2017-12-06 12:00:38.217187 HighlightedSearch[4439:1870645] w
2017-12-06 12:00:38.217575 HighlightedSearch[4439:1870645] 开始匹配,开始时间:2017-12-06 04:00:38 +0000
2017-12-06 12:00:38.253997 HighlightedSearch[4439:1870645] 匹配结束,结束时间:2017-12-06 04:00:38 +0000,耗时:0.0364
2017-12-06 12:00:38.616430 HighlightedSearch[4439:1870645] wa
2017-12-06 12:00:38.616807 HighlightedSearch[4439:1870645] 开始匹配,开始时间:2017-12-06 04:00:38 +0000
2017-12-06 12:00:38.654969 HighlightedSearch[4439:1870645] 匹配结束,结束时间:2017-12-06 04:00:38 +0000,耗时:0.0383
2017-12-06 12:00:38.948700 HighlightedSearch[4439:1870645] wan
2017-12-06 12:00:38.949453 HighlightedSearch[4439:1870645] 开始匹配,开始时间:2017-12-06 04:00:38 +0000
2017-12-06 12:00:38.986892 HighlightedSearch[4439:1870645] 匹配结束,结束时间:2017-12-06 04:00:38 +0000,耗时:0.0378
2017-12-06 12:00:39.280979 HighlightedSearch[4439:1870645] wang
2017-12-06 12:00:39.281563 HighlightedSearch[4439:1870645] 开始匹配,开始时间:2017-12-06 04:00:39 +0000
2017-12-06 12:00:39.317743 HighlightedSearch[4439:1870645] 匹配结束,结束时间:2017-12-06 04:00:39 +0000,耗时:0.0365
*/
for (WPFPerson *person in self.dataSource) {
最终选择的是forin循环,因为一般情况下 enumerateObjectsWithOptions 多线程是最快的,并且稍快于 dispatch_apply 方法,但是因为这个方法需要操作数组,因此必须将操作数据的那行代码加锁或者在指定线程进行,进行这个操作后效率反而不如其他单线程循环,考虑到搜索结果本来还要再次根据规则排序,就选择了 forin 循环
五. 为什么没有选择hash
首先最重要的一条是当前循环的方式也能满足需求(线上大概四千多条数据,使用过程中基本实时展现)
上文在需求分析中已举例,一个三个字的汉字对应的key值就有20多个甚至更多,在解析过程中是十分耗时的,但需求往往还存在类似微信的“群名称”匹配,每多一个字,对应的key值就多几个数量级
MapTable在高并发情况下,需要不断进行Resize(扩容 & Rehash),并且在Rehash 并发的情况下还可能形成链表环有个优化的思路,考虑到遍历的方式解析快,搜索匹配慢;hash的方式解析慢,搜索匹配快
通过遍历的方式先快速解析数据,此时搜索使用遍历的方式
然后再用hash的方式再次解析数据(考虑到hash表的扩容会使得瞬时效率的降低,为了避免频繁的扩容,先使用桶排序的方法将10个数字、26个英文字母、以及特殊符号开头的key分别放在37个字典里面,整体是一个数组。每个字典里面存放对应key和value),解析完成之后做个标记就采用hash的方式直接使用输入的key值去查询
配合DB缓存,效果应该是很棒的










