sprintf() は単なる文字列以上のものを処理するように設計されており、strcat() はスペシャリストです。しかし、あなたは小さなことに汗を流しているのではないかと思います。C 文字列は、これら 2 つの提案された方法の違いが重要でないという意味で、根本的に非効率的です。詳細については、Joel Spolsky の「Back to Basics」を参照してください。
これは、一般的に C++ が C よりも優れたパフォーマンスを発揮する例です。重い文字列の処理では、std::string を使用した方が効率的で確実に安全です。
[編集]
[2 回目の編集] 修正されたコード (C 文字列の実装で反復が多すぎる)、タイミング、および結論がそれに応じて変更されます
std::string の方が遅いという Andrew Bainbridge のコメントには驚きましたが、彼はこのテスト ケースの完全なコードを投稿していませんでした。彼を修正し(タイミングを自動化)、std::string テストを追加しました。テストは、VC++ 2008 (ネイティブ コード) で、デフォルトの "Release" オプション (つまり、最適化)、Athlon デュアル コア、2.6GHz で行われました。結果:
C string handling = 0.023000 seconds
sprintf = 0.313000 seconds
std::string = 0.500000 seconds
したがって、ここで strcat() は、C 文字列規則の固有の非効率性にもかかわらず、はるかに高速です (マイレージはコンパイラとオプションによって異なる場合があります)。 . ただし、可読性と安全性がはるかに低いままであるため、パフォーマンスが重要でない場合、IMO のメリットはほとんどありません。
また、std::stringstream の実装もテストしましたが、これもはるかに遅くなりましたが、複雑な文字列の書式設定にはまだメリットがあります。
修正されたコードは次のとおりです。
#include <ctime>
#include <cstdio>
#include <cstring>
#include <string>
void a(char *first, char *second, char *both)
{
for (int i = 0; i != 1000000; i++)
{
strcpy(both, first);
strcat(both, " ");
strcat(both, second);
}
}
void b(char *first, char *second, char *both)
{
for (int i = 0; i != 1000000; i++)
sprintf(both, "%s %s", first, second);
}
void c(char *first, char *second, char *both)
{
std::string first_s(first) ;
std::string second_s(second) ;
std::string both_s(second) ;
for (int i = 0; i != 1000000; i++)
both_s = first_s + " " + second_s ;
}
int main(void)
{
char* first= "First";
char* second = "Second";
char* both = (char*) malloc((strlen(first) + strlen(second) + 2) * sizeof(char));
clock_t start ;
start = clock() ;
a(first, second, both);
printf( "C string handling = %f seconds\n", (float)(clock() - start)/CLOCKS_PER_SEC) ;
start = clock() ;
b(first, second, both);
printf( "sprintf = %f seconds\n", (float)(clock() - start)/CLOCKS_PER_SEC) ;
start = clock() ;
c(first, second, both);
printf( "std::string = %f seconds\n", (float)(clock() - start)/CLOCKS_PER_SEC) ;
return 0;
}