之前师兄就说一个benchmark太少,拿差不多四个进行比较结果会丰厚一些。
从一开始的迷茫疑惑,到终于改好了剩下3个benchmark,分别是bsearch/bfs/heapsort
听上去还是比较有代表性吧。。。到时候老师问这是什么标准程序我就直接说是师兄给我的,甩锅
果然,全面的测试之后还是能发现一些问题
1.插桩阶段:循环体里包含if或else等其他语句体的},不能将他们}误判为循化结束(都想自己手动改了)
2.判断对象访问:
(1)循环里的if语句,可能有时候执行,有时候不执行,但是当if数组传进来时,【14,14,14】这三个说不定就是100次循环中唯一执行的三次。在我之前的代码中,对每一句是先判断的if再判断的循环,所以可能导致了一个循环体中的if语句只判断了一次,很不科学。
解决方式:初步想的是,判断if之前先看判断循环标志,如果是在循环体中,则对这个if语句判断n次,譬如上面的第14行判断100次,自然有三次是符合的(自然顺序就是不完全正确的)
如果循环体内有多个if语句 【14,17,14,14,17】这样如果对14行的if语句连续判断n次,由于后面跟了一个17,则会导致他认为只有一次
总结:最好是提前知道循环体的起止s-e(在插桩时记录下来),然后s-e循环n次,n作为外层循环,而非内层循环
双重循环的情况应该很难搞,外层s1-e1[n1] ,内层s2-e2[n2,是个数组,长度为n1,因为存在条件判断的情况,内层循环每次执行的次数不一定]
for(i:1~n1)
for(s1~e1){
encounter innner repeat{
for(1~n2[i]){
for(s2-e2)
}
}
}
(2)循环体里的调用函数语句,这就意味着这个函数要被多次调用
解决方式:和上面一样,把所有的循环体起止都记录下来(插桩时print语句把起止也输出来),遇到循环体时就里面的执行n次,这样自然可以把函数也调用多次。
for{
A=1
F(A)
B=1
}
梳理一下代码中的内容
distract函数最外层的循环肯定是子函数的起止行
repeatFlag = false;
doubleRepeatFlag = false;
for(i: fun.s~fun.e){
if(repeatFlag) continue;
if(i==repeat1.start){
repeatFlag = true;
for(j: 1~repeatCnt1){
for(k: repeat1.s~repeat1.e){
//还要判断双重循环
if(doubleRepeatFlag) continue;
if(k==repeat2.start){
doubleRepeatFlag = true;
for(m: repeat2.s~repeat2.e){
判断是否if是否执行,不执行continue
malloc\free\visit的判断
}
}
else{ if\malloc\free\visit\调用函数的判断} //对非内层循环语句
if(k==repeat2.end) doubleRepeatFlag=false;
}
}
else{ if\malloc\free\visit\调用函数的判断} //对非循环语句
if(i==repeat1.end) repeatFlag = false;
}
我试图这样改了代码 发现工作量实在太大了 果断决定不追求完全顺序 反正局部热也是直接看循环 循环体里if判断的事情从if数组传入时下点功夫解决吧