哨兵节点
1、概述
今天和同事一起调代码,定位到一处很耗时的地方,在某个线程中,同步周期需要保证在2ms(如果耗时不到2ms,那么让剩下的时间进行sleep).
但是在调用一个模块的内部函数时,时不时的就飘到了3~5ms,时间抖动毫无保证。后来仔细分析了一下被调用的函数,发现是在查找链表中某个目标节点时,由于目标节点的不确定行,导致耗时飘来飘去。
后来想到是否可以用“哨兵”的思路来解决问题,于是就试了一下,果然有效。特分享于此,使用2段代码来看一下代码执行效率的提升。
2、普通的算法
所谓哨兵,就是一个标志,一个与查找目标对象一样的操作对象。
假如有1000000个纸箱,每个箱子里面有一个纸条,里面写有1~1000000这些数字,数字不会重复。现在别人给一个随机的数字,我们需要从这1000000个箱子里找到与这个数字相同的纸条,找到之后退出操作。
分析:纸箱是无序的,所以我们需要从头遍历
(1)代码1
我们给一个500000的数字,要在这1000000个箱子中寻找纸条数字为500000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/time.h> #define LOOP_NUM 1000000 int main( void ) { long data[LOOP_NUM]; long rand_num = 500000; struct timeval tv1, tv2; for ( long i = 0;i < LOOP_NUM;i++) { data[i] = i; } gettimeofday(&tv1,0); for ( long i= 0;i<LOOP_NUM;i++) { if (data[i] == rand_num) { printf ( "find the box %ld\n" ,data[i]); break ; } } gettimeofday(&tv2, 0); long us1 = tv1.tv_sec * 1000000 + tv1.tv_usec; long us2 = tv2.tv_sec * 1000000 + tv2.tv_usec; printf ( "time elapse %ld\n" ,us2-us1); return 0; } |
我们使用for循环遍历所有的箱子查找,我们可以看到查找花了2840us.
(2)代码2(哨兵节点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | int main( void ) { long data[LOOP_NUM+1]; long rand_num = 500000,i=0; struct timeval tv1, tv2; for ( long i = 0;i < LOOP_NUM;i++) { data[i] = i; } data[LOOP_NUM] = 500000; /*增加一个哨兵节点*/ gettimeofday(&tv1,0); while (1) { if (data[i] == rand_num) { printf ( "find the box %ld\n" ,data[i]); if (i==LOOP_NUM) { printf ( "find the sentinal box\b" ); } break ; } i++; } gettimeofday(&tv2, 0); long us1 = tv1.tv_sec * 1000000 + tv1.tv_usec; long us2 = tv2.tv_sec * 1000000 + tv2.tv_usec; printf ( "time elapse %ldus.\n" ,us2-us1); return 0; } |
执行结果:
使用哨兵后,很明显提高了代码执行效率,代码1中使用for循环中对于i的最大值每个循环都要进行比较判断,这就降低了代码的执行效率,代码2加入了哨兵节点,多一个纸箱,纸箱里面的纸条写成500000。如果一直查找到哨兵节点才退出循环,表示没有找到。代码2中我们使用while循环,没有了每次箱子最大数量的比较判断,这就增加了代码的执行效率。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)