2

あるcharポインターから別のcharポインターに値をコピーする必要があるコードを書いています。主な要件は、コードができるだけ速く、できるだけ多くのプラットフォームで機能することです。

次の2つの関数のいずれかを使用して、この文字列コピーを実行できることがわかります。

char * strncpy ( char * destination, const char * source, size_t num );

void * memcpy ( void * destination, const void * source, size_t num );

要件に最適なものをどのように判断できますか?

一般に、2つの異なる関数(プラットフォーム間)の相対速度をどのように知ることができますか?

4

4 に答える 4

6

彼らは同じことをしません。ソース バッファとデスティネーション バッファが同じサイズであることが確実な場合は、 を使用してmemcpyください。そうでない場合は、strncpy境界チェックを行い、それが進むべき道です。

ただし、何百万もの操作を実行しない限り、これは決定の要因にはなりません。最初にいくつかのプロファイリングを行い、 を使用して節約できる時間 (ある場合) を確認しますmemcpy

于 2012-05-09T09:16:36.473 に答える
3

パフォーマンスPOVからmemcpyは、コンテンツ自体をチェックせず、コピーするだけなので、より高速です。

そして互換性に関して-memcpyはC標準の一部です。

于 2012-05-09T09:14:59.330 に答える
2

文字列をコピーする必要がある場合 (事前にサイズがわかっている場合を除く)、常に を使用する必要がありますstrncpy

基になる実装がmemcpyそれほど変わらなくても、何をコピーしているかをチェックする必要がないため、はるかに高速であり、文字列の末尾の文字( ) をstrncpyコピーすると停止します。NULL

EDITと比較して
のパフォーマンスに関するいくつかの考慮事項。 たとえば、512 バイトのバッファが 2 つあり、最初のバッファから 2 番目のバッファにコンテンツ (たとえば 32 文字の終端文字列) をコピーするとします。strncpymemcpy
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

memcpystrncpy前に話したコーナー ケース (PAGE_COPY_FWD_MAYBE を見てください) であっても、常に現実世界の状況よりも高速です。


大量に使用するため、あなたのケースではありませんが、一般的に、文字列をコピーする必要がある場合は strncpy を使用すると思います。いつも。おそらく、パフォーマンスを向上させる必要はありません。NULLターミネータが処理され、コードを読み取る文字列をコピーしていることは常に明確になります。
実際に多くの計算を行うため、ケースは異なります。バッファサイズがわかっている場合は、memcpyはるかに高速になる可能性があるため(特にバッファが小さくない場合)、使用する必要があります。

参照
デモの実装: http://clc-wiki.net/wiki/
memcpy のパフォーマンス テスト: http://eetimes.com/design/embedded/4024961/Optimizing-Memcpy-improves-speed

于 2012-05-09T09:19:36.363 に答える
1

ここで選択する機能には、異なる機能があります。必要なものを選択してください。

  • memcpy はすべてをコピーし、両方のバッファが同じサイズである必要があります
  • strncpy はより小さい c-string からコピーし、残りのターゲット バッファーを /0 で埋めます。
  • strcpy は、ターゲットから宛先に文字列のみをコピーします (ただし、安全なバリアントの 1 つを使用する必要があります)。

パフォーマンスについて: memcpy と strncpy の比較 - memcpy の方が高速ですが、入力文字列のサイズを知る必要があります。コピー中に必要なサイズを決定するため、文字列のサイズが大きく異なる場合は、strcpy が最も高速である可能性があります。

于 2012-05-09T09:21:39.857 に答える