seo常用优化技巧 网站代码优化工具( 三 )


哪怕你不增加预取代码,硬件预取器也有可能帮你做预取,另外gcc也有编译选项,开启它会在编译阶段自动插入预取代码,手动增加预取代码需要小心处理,时机的选择很重要,最后一定要基于测试数据,另外,即使预取表现很好,但代码修改也有可能导致效果衰减,而且预取语句执行本身也有开销,只有预取的收益大于预取的开销,且CACHE-MISS很高才是值得的 。
## 2、算法优化
数据量小的集合上遍历查找即可,但如果循环的次数过百,便需要考虑用更快的查找结构和算法替换蛮力遍历,哈希表,红黑树,二分查找很常用 。
### 哈希(HASH)
哈希也叫散列,是把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值,也叫摘要 。比如把一篇文章的内容通过散列生成64位的摘要,该过程不可逆 。
这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值,但如果输出的位数足够,散列成相同输出的概率非常非常小 。
字符串的比较有时会成为消耗较大的操作,虽然strcmp或者memcpy的实现用到了很多加速和优化技巧,但本质上它还是逐个比较的方式 。
字符串比较的一个改进方案就是哈希,比较哈希值(通常是一个int64的整数)而非比较内容能快很多,但需要为字符串提前计算好哈希值,且需要额外的空间保存哈希值,另外,在哈希值相等的时候,还需要比较字符串,但因为冲突的概率极低,所以后续的字符串比较不会很多次 。
这样不一定总是更高效,但它提供了另一个思路,你需要测试你的程序,再决定要不要这样做 。
另一个哈希的用法是哈希表,哈希表的经典实现是提前开辟一些桶,通过哈希找到元素所在的桶(编号),如果冲突,再拉链解决冲突 。
为了减少冲突经常需要开辟更多的桶,但更多的桶需要更大的存储空间,特别是元素数量不确定的时候,桶的数量选择变得两难,随着装载的元素变多,冲突加剧,在扩容的时候,将需要对已存在的元素重新哈希,这是很费的点 。
哈希表的冲突极端情况下会退化成链表,当初设想的快速查找变得不再可行,HashMap是普通哈希表的改进版,结合哈希和二叉平衡搜索树 。
另一个常用来做查找的结构是红黑树,它能确保最坏情况下,有logN的时间复杂度,但红黑树的查找过程需要沿着链走,不同结点内存通常不连续,CACHE命中性经常很差,红黑树的中序遍历结果是有序的,这是哈希表不具备的,另外,红黑树不存在哈希表那般预估容量难的问题 。
### 基于有序数组的二分查找
二分查找的时间复杂度也是logN,跟红黑树一致,但二分查找的空间局部性更好,不过二分查找有约束,它只能在有序数组上进行,所以,如果你需要在固定的数据集合(比如配置数据)做查找,二分查找是个不错的选择 。
### 跳表(Skip List)
跳表增加了向前指针,是一种多层结构的有序链表,插入一个值时有一定概率晋升到上层形成间接的索引 。
跳表是一个随机化的数据结构,实质就是一种可以进行二分查找的有序链表 。跳表在原有的有序链表上面增加了多级索引,通过索引来实现快速查找 。跳表不仅能提高搜索性能,同时也可以提高插入和删除操作的性能 。
跳表适合大量并发写的场景,可以认为是随机平衡的二叉搜索树,不存在红黑树的再平衡问题 。Redis强大的ZSet底层数据结构就是哈希加跳表 。


以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!

「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助: