我有一些在一个函数中大量使用strcasecmp
的代码(请参见版本1)。因此,我想知道是否应该将其更改为大写或小写,strcmp
(如版本2中)以符合c并具有更好的性能,因为我只需要将其转换为大写或小写即可。 -情况一次。
char pname[5]="TEST";
//version 1
if(strcasecmp(pname,"TEST")==0)
{
printf("%s\n", pname);
}
//version 2
for(int i=0;i<5;++i)
{
pname[i]=toupper(pname[i]);
}
if(strcmp(pname,"TEST")==0)
{
printf("%s\n", pname);
}
答案 0 :(得分:1)
我认为您的意思是更好的性能,即更少的操作。
比方说:
x = tolower()/ toupper()的时间
n =字符串[n]操作的时间
也
最佳情况(最快完成时间)=不匹配
最坏情况(最长的完成时间)=字符串匹配
这些计算假设我们只需要在代码中显示的一个字符串上降低/提高
版本1:(strcasecmp)
最佳情况= 1 + x [即对第一个字符的上下位置进行一次操作-不匹配]
最坏的情况= n +(x * n)[即下/上-字符串匹配的n个操作]
-平均值=(n *(x + 1)+ x + 1)/ 2
版本2 (上下/上下+ strcmp)
最佳情况= 1 +(x * n)[即n个字符的上下移动操作-不匹配]
最坏情况= n [即对所有字符进行n次操作]
-平均值=(1 + n *(x + 1))/ 2
结论
因此与版本2的不同之处在于,它改善了最坏的情况,但这样做却恶化了最好的情况。但是,一般情况下,版本2更快。
即如果您事先像版本2中那样将整个字符串更改为大写或小写,则您必须已经循环遍历字符串中的每个字符,因为字符串可能根本不匹配,可能不需要这样做,这会增加额外的操作,不需要。
此外,根据所使用的编译器的不同,使用索引的for循环并不是特别快,使用以下命令可以更快:
while (*chptr)
{
// do stuff with *chptr
chptr++;
}
用于字符串。
答案 1 :(得分:1)
在Linux内核中,strcmp
的实现方式如下
int strcmp(const char *cs, const char *ct)
{
unsigned char c1, c2;
while (1) {
c1 = *cs++;
c2 = *ct++;
if (c1 != c2)
return c1 < c2 ? -1 : 1;
if (!c1)
break;
}
return 0;
}
strcasecmp
的实现方式如下
int strcasecmp(const char *s1, const char *s2)
{
int c1, c2;
do {
c1 = tolower(*s1++);
c2 = tolower(*s2++);
} while (c1 == c2 && c1 != 0);
return c1 - c2;
}
tolower
的实现方式如下
static inline unsigned char __tolower(unsigned char c)
{
if (isupper(c))
c -= 'A'-'a';
return c;
}
因此,我发现您的version1
与version2
之间的性能差异不大。就个人而言,我更喜欢version1
比version2
。虽然它更干净。 :)