文字列をコピーする必要がある場合 (事前にサイズがわかっている場合を除く)、常に を使用する必要がありますstrncpy
。
基になる実装がmemcpy
それほど変わらなくても、何をコピーしているかをチェックする必要がないため、はるかに高速であり、文字列の末尾の文字( ) をstrncpy
コピーすると停止します。NULL
EDITと比較して
のパフォーマンスに関するいくつかの考慮事項。
たとえば、512 バイトのバッファが 2 つあり、最初のバッファから 2 番目のバッファにコンテンツ (たとえば 32 文字の終端文字列) をコピーするとします。strncpy
memcpy
NULL
何strncpy
をするか: ソースからターゲットにバイトごとにコピーします。文字をコピーすると停止し、NULL
他のすべてを 0 に設定します。これは、この関数の可能な実装です。
char *strncpy(char *dest, const char *src, size_t n)
{
char *ret = dest;
do {
if (!n--)
return ret;
} while (*dest++ = *src++);
while (n--)
*dest++ = 0;
return ret;
}
何memcpy
をするか: ソースからターゲットにすべてを一括コピーします。これは、この関数の可能な実装です:
void *memcpy(void *dest, const void *src, size_t n)
{
char *dp = dest;
const char *sp = src;
while (n--)
*dp++ = *sp++;
return dest;
}
両方のバージョンが最適化されていない場合でも、実行する操作がはるかに少ないことがわかりますが、文字列の長さがバッファーの合計長よりもはるかに短い場合にのみ遅くなる可能性があります ( *sp++
2 番目の に保存されますwhile
)。したがって、実際の入力に依存するため、パフォーマンスのテストでさえ信頼できません(したがって、実際の世界からのある種の統計データが必要です)。
考慮事項
さらに、真の実装はそれほど単純ではないことを覚えておく必要があります!!! この実装を見てくださいstrncpy
:
http://sourceware.org/git/?p=glibc.git;a=blob;f=string/strncpy.c;h=f6ee27832da95d9da9aef8a6fcf73f53f997c796;hb=HEAD
memcpy
実装
を見てみましょう: http://sourceware.org/git/?p=glibc.git;a=blob;f=string/memcpy.c;h=3080fcb4de4cec83a57b65bf07995a1e41abb1f6;hb=HEAD
memcpy
strncpy
前に話したコーナー ケース (PAGE_COPY_FWD_MAYBE を見てください) であっても、常に現実世界の状況よりも高速です。
注
大量に使用するため、あなたのケースではありませんが、一般的に、文字列をコピーする必要がある場合は strncpy を使用すると思います。いつも。おそらく、パフォーマンスを向上させる必要はありません。NULLターミネータが処理され、コードを読み取る文字列をコピーしていることは常に明確になります。
実際に多くの計算を行うため、ケースは異なります。バッファサイズがわかっている場合は、memcpy
はるかに高速になる可能性があるため(特にバッファが小さくない場合)、使用する必要があります。
参照
デモの実装: http://clc-wiki.net/wiki/
memcpy のパフォーマンス テスト: http://eetimes.com/design/embedded/4024961/Optimizing-Memcpy-improves-speed