いつも勉強させて頂きありがとうございます。
質問なのですが、一般的にC言語において
構造体のコピーを行う場合
memcpy()する or 代入する
の二通りがあるかと思いますが、
実行速度の違いはあるのでしょうか?
VC++2005でのアセンブリコードを見ると
memcpy()の場合はアドレスをスタックにつんで
memcpy関数のコールを行い、
代入の場合は構造体のメンバをmovでコピーしていくだけでした。
構造体のメンバ数などにも影響があるとは思いますが、
どちらがベターなんでしょうか?
なんとなく今までmemcpy()しか使ってませんでしたが
みなさんはどうなんでしょうか?
俺なら代入する。
理由は2つ。
・どちらでもパフォーマンスに大した違いはないこと。
・意味的に直感的であり、また高レベルであること。
>シャノンさま
レスありがとうございます。
>・意味的に直感的であり、また高レベルであること。
~~~~~~~~
何が高レベルなのでしょうか?
> 何が高レベルなのでしょうか?
コンピュータ用語で言う時の「低レベル」「高レベル」の意味はご存知ですか?
「低レベル」とは、ハードウェア寄りだとか、実装を意識した処理という意味。
反対に「高レベル」とは、ハードウェアを意識しない、抽象的な処理という意味です。
今回やりたいのは「構造体のコピー」です。それ以上でもそれ以下でもありません。
例えば、3つ目の折衷案を出してみましょう。
構造体の各メンバに対して、それぞれ代入文を書くことでも、同じ目的は達せられま
す。
1:各メンバに対して mov 命令を実行する
2:各メンバに対して代入文を記述する
3:構造体を丸ごと代入する
この3つを比較すると、上ほど低レベルで、下ほど高レベルです。
1と2を比較すると、1は x86 互換 CPU を意識したコーディングになっているのに対
し、2は C 言語のレベルでの記述になっていますから、非 x86 CPU であっても、C コ
ンパイラがあるマシンなら通用する書き方です。ハードウェアを意識しないため、2の
方が高レベルだと言えます。
2と3を比較すると、やりたいことを、より素直に記述しているのは3です。
「やりたいことを、そのままストレートに書く」のと「どのように実現されているかを
考えて、その中身を書く」のでは、前者の方が高レベルだと言えるでしょう。
で、本題である代入と memcpy の比較ですが…
memcpy は「汎用的なメモリコピー関数」です。
例えば、SomeStruct 型の2つの変数 s と d があったとして、
memcpy( &d, &s, sizeof( SomeStruct ) );
この行の意味は何でしょう?
これは、「s のアドレスから d のアドレスへ、SomeStruct のサイズ分のデータをコピ
ーする」ことを意味しています。
s と d が共に SomeStruct 型であり、コピーするバイト数も SomeStruct のサイズなの
で、結果的に構造体間のコピーになってはいますが、それはあくまで結果論です。ぶっ
ちゃけて言えば、たまたまです。都合のいいパラメータの組み合わせを渡したから構造
体間のコピーになったというだけの話です。
このコードからは、「構造体間のコピー」という意味が欠落してしまっています。
しかし、このコード
d = s;
の意味は単純で明確です。これは構造体間のコピーを意図して書かれたコードであり、
それ以外の意図の読み取りようがありません。
先程の言葉を使えば、「やりたいことを、より素直に記述したコード」だと言えます。
一般的に、高レベルな書き方をすると、
・コードの意味が汲み取りやすくなります
・プログラムが簡潔で短くなります
・そのため、メンテナンス性が向上します
・代償として、実行が遅くなる場合があります
というような特徴があります。
そのため、パフォーマンスがさほど問題にならない場合は、高レベルに書けるならその
ほうがよい、と言えるでしょう。
>シャノンさま
詳しい解説ありがとうございます。
いわゆる組込み用のアプリケーション開発を
行っていまして、パフォーマンス(=実行速度)が
最優先事項なのですがアセンブリレベルでも
やっていることはそう変わらないようなので
代入による構造体のコピーを採用していきたいと思います。
どうもありがとうございました。
> いわゆる組込み用のアプリケーション開発を
> 行っていまして、パフォーマンス(=実行速度)が
> 最優先事項なのですが
そういうことは先に言おうよ。
俺が言ったのは一般論なので、特定分野では通用しない可能性があります。
組み込み系の場合、使用するCPUの種類とかその他の環境により
得意な処理と不得意な処理が出てきますね。
そのCPU用のコンパイラの出来も影響します。
なので一般のアプリケーションと組み込み系のソフトの場合は
分けて考える必要があります。
シャノンさんの言うとおり、この部分はレスの内容に影響が出る部分なので
必ず、開発環境とともに提示するべきです。