構造体のコピーについて

[戻る]
mazy 2006/05/19(金) 20:57:12
いつも勉強させて頂きありがとうございます。
質問なのですが、一般的にC言語において
構造体のコピーを行う場合

memcpy()する or 代入する

の二通りがあるかと思いますが、
実行速度の違いはあるのでしょうか?

VC++2005でのアセンブリコードを見ると
memcpy()の場合はアドレスをスタックにつんで
memcpy関数のコールを行い、
代入の場合は構造体のメンバをmovでコピーしていくだけでした。

構造体のメンバ数などにも影響があるとは思いますが、
どちらがベターなんでしょうか?

なんとなく今までmemcpy()しか使ってませんでしたが
みなさんはどうなんでしょうか?

シャノン 2006/05/19(金) 21:47:40
俺なら代入する。
理由は2つ。

・どちらでもパフォーマンスに大した違いはないこと。
・意味的に直感的であり、また高レベルであること。

mazy 2006/05/19(金) 22:08:14
>シャノンさま
 レスありがとうございます。

>・意味的に直感的であり、また高レベルであること。
               ~~~~~~~~
何が高レベルなのでしょうか?

シャノン 2006/05/19(金) 22:38:42
> 何が高レベルなのでしょうか?

コンピュータ用語で言う時の「低レベル」「高レベル」の意味はご存知ですか?
「低レベル」とは、ハードウェア寄りだとか、実装を意識した処理という意味。
反対に「高レベル」とは、ハードウェアを意識しない、抽象的な処理という意味です。

今回やりたいのは「構造体のコピー」です。それ以上でもそれ以下でもありません。

例えば、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;

の意味は単純で明確です。これは構造体間のコピーを意図して書かれたコードであり、
それ以外の意図の読み取りようがありません。
先程の言葉を使えば、「やりたいことを、より素直に記述したコード」だと言えます。

一般的に、高レベルな書き方をすると、
・コードの意味が汲み取りやすくなります
・プログラムが簡潔で短くなります
・そのため、メンテナンス性が向上します
・代償として、実行が遅くなる場合があります
というような特徴があります。
そのため、パフォーマンスがさほど問題にならない場合は、高レベルに書けるならその
ほうがよい、と言えるでしょう。

mazy 2006/05/19(金) 23:15:02
[[解決]]
>シャノンさま

 詳しい解説ありがとうございます。
 いわゆる組込み用のアプリケーション開発を
 行っていまして、パフォーマンス(=実行速度)が
 最優先事項なのですがアセンブリレベルでも
 やっていることはそう変わらないようなので
 代入による構造体のコピーを採用していきたいと思います。

 どうもありがとうございました。

シャノン 2006/05/20(土) 08:32:19
> いわゆる組込み用のアプリケーション開発を
> 行っていまして、パフォーマンス(=実行速度)が
> 最優先事項なのですが

そういうことは先に言おうよ。
俺が言ったのは一般論なので、特定分野では通用しない可能性があります。

PATIO 2006/05/22(月) 10:20:21
組み込み系の場合、使用するCPUの種類とかその他の環境により
得意な処理と不得意な処理が出てきますね。
そのCPU用のコンパイラの出来も影響します。
なので一般のアプリケーションと組み込み系のソフトの場合は
分けて考える必要があります。
シャノンさんの言うとおり、この部分はレスの内容に影響が出る部分なので
必ず、開発環境とともに提示するべきです。

古いスレッドには追加発言できません。