字符串拼接性能差的原因是内存重新分配。Joel Spolsky在他的文章
Back to basics中讨论了这个问题。他描述了一种朴素的字符串拼接方法:
舍米尔成为了一名街头画家,负责画路中间的虚线。第一天,他拿着一桶油漆走到路上,完成了300码的路线。 "太棒了!"他的老板说,"你是个快速工作者!"并给了他一枚戈比。
第二天,舍米尔只完成了150码。 "嗯,显然不如昨天好,但你仍然是一个快速工作者。150码还算可以接受。"老板付给了他一枚戈比。
第三天,舍米尔只刷了30码的路线。 "只有30码!"老板大声喊道。 "这是不能接受的!第一天你完成了那么多的工作!发生了什么事?"
"我没办法,"舍米尔说。 "每天我离油漆桶越来越远了!"
如果可能的话,您希望在分配缓冲区之前知道目标缓冲区需要多大。唯一现实的方法是对您想要连接的所有字符串调用
strlen
。然后分配适当数量的内存并使用略微修改的
strncpy
版本,该版本返回指向目标缓冲区结尾的指针。
char* StringCopyEnd( char* dest, char* src, size_t size )
{
size_t pos = 0;
if ( size == 0 ) return dest;
while ( pos < size - 1 && *src )
{
*dest = *src;
++dest;
++src;
++pos;
}
*dest = '\0';
return dest;
}
请注意,您必须将
size
参数设置为目标缓冲区剩余的字节数。
以下是一个示例测试函数:
void testStringCopyEnd( char* str1, char* str2, size_t size )
{
char* dest = (char*) malloc( size + 10 );
memset( dest, 'A', size + 10 );
char* end = StringCopyEnd( dest, str1, size );
end = StringCopyEnd( end, str2, size - ( end - dest ) );
printf( "length: %d - '%s'\n", strlen( dest ), dest );
}
int main(int argc, _TCHAR* argv[])
{
for ( int i = 12; i > 0; --i )
{
testStringCopyEnd( "Hello", " World", i );
}
return 0;
}
这句话的意思是“产生以下内容:”。
length: 11 - 'Hello World'
length: 10 - 'Hello Worl'
length: 9 - 'Hello Wor'
length: 8 - 'Hello Wo'
length: 7 - 'Hello W'
length: 6 - 'Hello '
length: 5 - 'Hello'
length: 4 - 'Hell'
length: 3 - 'Hel'
length: 2 - 'He'
length: 1 - 'H'
length: 0 - ''