Xan*_*ndy 56 c string performance concatenation
我遇到了这两种连接字符串的方法:
共同部分:
char* first= "First";
char* second = "Second";
char* both = malloc(strlen(first) + strlen(second) + 2);
Run Code Online (Sandbox Code Playgroud)
方法1:
strcpy(both, first);
strcat(both, " "); // or space could have been part of one of the strings
strcat(both, second);
Run Code Online (Sandbox Code Playgroud)
方法2:
sprintf(both, "%s %s", first, second);
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,内容both都是"First Second".
我想知道哪一个更有效(我必须执行几个连接操作),或者如果你知道更好的方法来做到这一点.
Chr*_*oph 72
为了便于阅读,我会选择
char * s = malloc(snprintf(NULL, 0, "%s %s", first, second) + 1);
sprintf(s, "%s %s", first, second);
Run Code Online (Sandbox Code Playgroud)
如果您的平台支持GNU扩展,您还可以使用asprintf():
char * s = NULL;
asprintf(&s, "%s %s", first, second);
Run Code Online (Sandbox Code Playgroud)
如果您遇到MS C Runtime,则必须使用_scprintf()确定结果字符串的长度:
char * s = malloc(_scprintf("%s %s", first, second) + 1);
sprintf(s, "%s %s", first, second);
Run Code Online (Sandbox Code Playgroud)
以下很可能是最快的解决方案:
size_t len1 = strlen(first);
size_t len2 = strlen(second);
char * s = malloc(len1 + len2 + 2);
memcpy(s, first, len1);
s[len1] = ' ';
memcpy(s + len1 + 1, second, len2 + 1); // includes terminating null
Run Code Online (Sandbox Code Playgroud)
Ned*_*der 24
不要担心效率:使代码可读和可维护.我怀疑这些方法之间的区别在你的程序中是否重要.
And*_*dge 18
这对你来说有点疯狂,我实际上是去衡量它.血淋淋的地狱,想象一下.我想我得到了一些有意义的结果.
我使用双核P4,运行Windows,使用mingw gcc 4.4,使用"gcc foo.c -o foo.exe -std = c99 -Wall -O2"构建.
我测试了原始帖子中的方法1和方法2.最初将malloc保留在基准循环之外.方法1比方法2快48倍.奇怪的是,从构建命令中删除-O2使得生成的exe快30%(尚未调查原因).
然后我在循环中添加了一个malloc并且自由了.这使方法1减慢了4.4倍.方法2减慢了1.1倍.
因此,malloc + strlen + free不会在配置文件中占主导地位,足以避免sprintf值得.
这是我使用的代码(除了循环用<而不是!=实现,但这打破了这篇文章的HTML呈现):
void a(char *first, char *second, char *both)
{
for (int i = 0; i != 1000000 * 48; i++)
{
strcpy(both, first);
strcat(both, " ");
strcat(both, second);
}
}
void b(char *first, char *second, char *both)
{
for (int i = 0; i != 1000000 * 1; i++)
sprintf(both, "%s %s", first, second);
}
int main(void)
{
char* first= "First";
char* second = "Second";
char* both = (char*) malloc((strlen(first) + strlen(second) + 2) * sizeof(char));
// Takes 3.7 sec with optimisations, 2.7 sec WITHOUT optimisations!
a(first, second, both);
// Takes 3.7 sec with or without optimisations
//b(first, second, both);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
size_t lf = strlen(first);
size_t ls = strlen(second);
char *both = (char*) malloc((lf + ls + 2) * sizeof(char));
strcpy(both, first);
both[lf] = ' ';
strcpy(&both[lf+1], second);
Run Code Online (Sandbox Code Playgroud)