strcasecmp和tolower/toupper+strcmp哪个更好



我有一些代码在一个函数中大量使用strcasecmp(请参阅版本1(。因此,我想知道我是否应该将其更改为大写或小写,并将strcmp(如版本2中(更改为c兼容并具有更好的性能,因为这样我只需要将其转换为大写或大写一次。

char pname[5]="TEST";
//version 1
if(strcasecmp(pname,"TEST")==0)
{
printf("%sn", pname);
}
//version 2
for(int i=0;i<5;++i)
{
pname[i]=toupper(pname[i]);
}
if(strcmp(pname,"TEST")==0)
{
printf("%sn", pname);
}

我认为性能更好,也就是说操作更少。

比方说:

x=tolower((/toupper((的时间

n=字符串[n]操作的时间

还有

最佳情况(最快完成时间(=不匹配

最坏情况(最长完成时间(=字符串匹配

这些计算假设我们只需要对您的代码中所示的一个字符串进行降功率/映射

版本1:(strcasecmp(

最佳情况=1+x[即第一个字符上下一个操作-不匹配]

最坏情况=n+(x*n([即到下/上字符串匹配的n个操作]

--平均值=(n*(x+1(+x+1(/2

版本2(tolower/upper+strcmp(

最佳情况=1+(x*n([即所有字符上的n次下/上运算-不匹配]

最坏情况=n[即对所有字符进行n次操作]

--平均值=(1+n*(x+1((/2

结论

因此,与版本2的不同之处在于,is改善了最坏的情况,但却恶化了最好的情况。然而,在一般情况下,版本2更快。

即,如果您像之前的版本2那样将整个字符串更改为大写或小写,那么您必须循环遍历字符串中的每个字符,这可能是不需要的,因为字符串可能根本不匹配,从而添加不需要的额外操作。

此外,根据您使用的编译器,使用索引的for循环不是特别快,使用会更快

while (*chptr)
{
// do stuff with *chptr
chptr++;
}

用于字符串。

在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;
}

所以我看不出您的version1version2之间有太大的性能差异。就我个人而言,我更喜欢version1而不是version2。不过它要干净得多。:(

最新更新