【发布时间】:2018-06-07 00:57:39
【问题描述】:
我目前正在做一个依赖 strcmp 时序优化的项目。例如,给定两个字符串 a1, a2 其中 a1=a2 和两个字符串 b1, b2 where b1=/=b2 我们知道 strcmp (a1,a2) 在理论上比 strcmp(b1,b2) 需要更长的时间来完成,因为 strcmp一旦它意识到第一个字符串中的一个字节不等于第二个字符串中的相应字节,这意味着当两个字符串相等时 strcmp 将花费最长的时间来完成,因为它需要遍历整个长度。我的项目目前正在使用各种字符串对 strcmp 的性能进行计时,它的成功取决于一次调用 strcmp 是否比另一次调用更快,即使正在比较的两个字符串中的一个字节是关闭的。
我创建了一个更简单的虚拟程序来隔离和测试性能(虚拟程序如下),它比较了比较两个相等字符串的性能与两个不相等字符串的性能。参考代码,当 str3="aaaaaaaaaa"(或与 str1 有很大差异的任何随机文本)时,很明显,比较两个相等字符串(str1 和 str2)的第一段比比较两个不相等字符串的第二段慢得多(str2 和 str3)。但是,当如下所示切换 str3="hellohella" 时,结果非常相似,并且确定哪个段完成得更快/更慢变得不可预测。我也尝试过使用 clock() 来为函数调用计时,但这比 rusage 更不准确。
有什么方法可以改变我的代码,使两个不相等的字符串的比较总是比两个相等的字符串的比较快(即使只有 1 个字节)?有没有比我尝试过的更准确的 C 计时器?感谢您的宝贵时间。
int main ()
{
int iterations=10000;
struct rusage usage;
struct timeval start, end;
char * str1="hellohello";
char * str2="hellohello";
char * str3="hellohella";
double tempTotal=0;
for (int i=0; i<iterations; i++){
struct rusage usage;
struct timeval start, end;
getrusage(RUSAGE_SELF, &usage);
start=usage.ru_stime;
for (int j=0; j<100000; j++) strcmp(str1, str2);
getrusage(RUSAGE_SELF, &usage);
end=usage.ru_stime;
double startTime=((double)start.tv_sec + (double)start.tv_usec)/10000;
double endTime=((double)end.tv_sec+(double)end.tv_usec)/10000;
tempTotal+=(endTime-startTime);
}
printf("Avg time taken: %f\n", tempTotal/iterations);
printf("\n\n");
double tempTotal2=0;
for (int i=0; i<iterations; i++){
struct rusage usage2;
struct timeval start2, end2;
getrusage(RUSAGE_SELF, &usage2);
start2=usage2.ru_stime;
for (int j=0; j<100000; j++) strcmp(str1, str3);
getrusage(RUSAGE_SELF, &usage2);
end2=usage2.ru_stime;
double startTime2=((double)start2.tv_sec+(double)start2.tv_usec)/10000;
double endTime2=((double)end2.tv_sec+(double)end2.tv_usec)/10000;
tempTotal2+=endTime2-startTime2;
}
printf("Avg time taken: %f\n", tempTotal2/iterations);
return 0;
}
【问题讨论】:
-
但是,不相等的字符串总是需要更短的时间来比较相等的字符串,这并不正确——除非您只对相同长度的字符串感兴趣。
-
请注意,
(double)end2.tv_usec)/10000应该是(double)end2.tv_usec)/1000000(至少在 4 个不同的地方)。 -
如果您的计时器不够准确,当然,您可以随时增加迭代次数。我通常要求实验至少需要 30 秒(如果不是更多),这通常需要数千万或数亿次迭代,甚至更多。 (如果迭代次数超过适合 32 位整数的次数,则必须使用两个嵌套循环并不少见。)计算机 快速。
-
@Steve Summit 是的,对不起,我的意思是说我只研究相同长度的字符串。我会尝试实施您的其他建议,谢谢。
标签: c string optimization strcmp