プログラム

C++:memcpyってただの代入じゃない?

このページを見るとどうなるか

memcpy関数ってただの代入じゃないって気づける。やったね♪

疑問に思ったきっかけ

C言語を使って、例えば、ループを使って1バイトずつ加工して代入するケースがあります。(画像加工だったりメッセージ加工だったり)

なんか歴戦プログラマが作ったプログラムで、例えばfor文で1バイトずつ代入ではなく、たまにmemcpyで代入するのを見かけたりして、「これって何か意味あるの?」「ビルド後、機械語になったとき意味一緒じゃないの?」と思った事がありました。

試してみればいい

実際にどう違うのか試してみました。
以下、サンプルプログラムになります。

ここで、malloc関数で動的にメモリ確保している理由は、膨大な量のメモリを確保するためです。 unsigned char bufA[1024 * 1024 * 512];と定義すると、メモリ確保できないとビルドエラーになるか、実行エラーになります。
環境によって定義できる範囲に限界があるかもしれません。それでもエラーになる場合は、バッファサイズを下げたりしてお試しください。

サンプルプログラム

#include <iostream>
#include <time.h>     // clock()

#define DEF_BUF_SIZE    1024 * 1024 * 512

int main()
{
    int i;
    clock_t clst;
    clock_t cled;
    unsigned char* bufA;
    unsigned char* bufB;

    bufA = (unsigned char*)malloc(DEF_BUF_SIZE);
    bufB = (unsigned char*)malloc(DEF_BUF_SIZE);

    // 0で初期化
    memset( bufA, 0, DEF_BUF_SIZE );
    memset( bufB, 0, DEF_BUF_SIZE );

    std::cout << "----------for文で1byteずつ代入----------\n";
    clst = clock();
    // bufAの中身をすべて1で代入
    for ( i = 0; i < DEF_BUF_SIZE; i++ ) {
        bufA[i] = 1;
    }
    cled = clock();
    std::cout << "経過時間 = " << (double)(cled - clst) / CLOCKS_PER_SEC << "\n";

    std::cout << "----------memcpyでまとめて代入----------\n";
    clst = clock();
    // bufBの中身をすべて0で代入
    memcpy( bufA, bufB, DEF_BUF_SIZE );
    cled = clock();
    std::cout << "経過時間 = " << (double)(cled - clst) / CLOCKS_PER_SEC << "\n";

    free( bufA );
    free( bufB );
}

実行結果

———-for文で1byteずつ代入———-
経過時間 = 0.982
———-memcpyでまとめて代入———-
経過時間 = 0.116

思いのほか歴然。

やっていることは一緒に見えても、機械語に翻訳すると別物なんでしょうね。

処理速度を気にするような処理の場合は、気にしていたほうがよいでしょう。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA