ページ 1 / 1
関数の呼び出し速度
Posted: 2011年10月23日(日) 20:10
by kyou.s
はじめまして
最近、DXライブラリでプログラムというものを触り始めた初心者です
質問は関数の呼び出し速度のことなのですが
今、とある小さなゲームを作っております
キャラとキャラの当たり判定は矩形にしていて
キャラ構造体には表示座標のほかに画像の縦と横の大きさを記憶させています
(矩形の当たり判定に使用するためです)
そこで、ある悩み事が発生します
縦と横の大きさをプログラムに数値で記述しておくか、
DXライブラリの画像の大きさを調べる関数を使うか、どちらにするかということです
後者の方は一見、楽そうですが関数の呼び出しはかなりの負担になると聞いたことがあります
今は小さいプログラムなのでいいですが大きくなった場合は致命的なのでしょうか?
それと、タイトルとは関係ないけどもう一つ質問があります
画像の読み込み関数についてなのですが読込は結構な時間がかかりますよね
読み込んでいる間は流しているBGMなどは途切れてしまいます
それが気に食わないのですがどうやら非同期読込というのがあるそうです
しかし、非同期読込はかなり遅いそうです
この非同期読込というものを使わなければいけないのでしょうか?
もし、そうでしたら使い方も教えていただきたい(URLでも結構でございます)
自分はお話が苦手なので伝わってないかもしれませんが
分かる方がいましたらどうかよろしくお願いします
Re: 関数の呼び出し速度
Posted: 2011年10月23日(日) 21:10
by softya(ソフト屋)
kyou.s さんが書きました:質問は関数の呼び出し速度のことなのですが
今、とある小さなゲームを作っております
キャラとキャラの当たり判定は矩形にしていて
キャラ構造体には表示座標のほかに画像の縦と横の大きさを記憶させています
(矩形の当たり判定に使用するためです)
そこで、ある悩み事が発生します
縦と横の大きさをプログラムに数値で記述しておくか、
DXライブラリの画像の大きさを調べる関数を使うか、どちらにするかということです
後者の方は一見、楽そうですが関数の呼び出しはかなりの負担になると聞いたことがあります
今は小さいプログラムなのでいいですが大きくなった場合は致命的なのでしょうか?
「DXライブラリの画像の大きさを調べる関数」の呼び出しは大した負担にはならないと思いますが、当たり判定処理内での呼び出しだと呼び出す回数が多いので弾幕シューティングのタマ数レベルの当たり判定だと負担になるかも知れません。
まぁ、想定される呼び出しをテストしてみるのが一番ですので時間計測を試してみるってクセを付ける意味でもやってみたらどうでしょうか?
今後のプログラミングのためにも必要なスキルだと思います。
あと縦と横の大きさは構造体で持てば良いので、ロード時に「DXライブラリの画像の大きさを調べる関数」を一回読んでサイズを記録してけば負担にはなりませんし、プログラムで記述する必要もなくなります。これで解決するかも知れませんが、半透明部分を含んだ大きさの当たり判定で果たして感覚的に許せるのかっての別の問題です。
kyou.s さんが書きました:
それと、タイトルとは関係ないけどもう一つ質問があります
画像の読み込み関数についてなのですが読込は結構な時間がかかりますよね
読み込んでいる間は流しているBGMなどは途切れてしまいます
それが気に食わないのですがどうやら非同期読込というのがあるそうです
しかし、非同期読込はかなり遅いそうです
この非同期読込というものを使わなければいけないのでしょうか?
もし、そうでしたら使い方も教えていただきたい(URLでも結構でございます)
PlaySoundFile()をDX_PLAYTYPE_BACKで使われてますか?
違っていたら一度試してみてください。
Re: 関数の呼び出し速度
Posted: 2011年10月23日(日) 21:31
by bitter_fox
kyou.s さんが書きました:
キャラ構造体には表示座標のほかに画像の縦と横の大きさを記憶させています
(矩形の当たり判定に使用するためです)
そこで、ある悩み事が発生します
縦と横の大きさをプログラムに数値で記述しておくか、
DXライブラリの画像の大きさを調べる関数を使うか、どちらにするかということです
後者の方は一見、楽そうですが関数の呼び出しはかなりの負担になると聞いたことがあります
今は小さいプログラムなのでいいですが大きくなった場合は致命的なのでしょうか?
構造体に記憶させるという事なので呼び出しは最初の一回で済むので気にするレベルではないでしょう。
またマジックナンバーを用いる方が問題が大きいのでそういったことは極力しないでください。
http://ja.wikipedia.org/wiki/%E3%83%9E% ... 3%83%A0%29
特に今回は画像の大きさが変わった時に、関数を用いていればソースコードを弄らなくても良いのに対しマジックナンバーを用いているとソースコードにある数値を正確に書き換えないといけないのでより問題は深刻です。
そもそも関数ひとつの呼び出しでそう負荷になるということは無いと思います。
それに21世紀ですしCPUもコアなんたらになっておりそんなみみっちいレベルでプログラムを組まなければいけないような環境ではないので、気にせずバンバン呼び出してよいでしょう。
あと、関数呼び出しの負荷よりも関数自体の処理の負荷を考慮する必要があると思います。
kyou.s さんが書きました:
画像の読み込み関数についてなのですが読込は結構な時間がかかりますよね
読み込んでいる間は流しているBGMなどは途切れてしまいます
それが気に食わないのですがどうやら非同期読込というのがあるそうです
しかし、非同期読込はかなり遅いそうです
この非同期読込というものを使わなければいけないのでしょうか?
もし、そうでしたら使い方も教えていただきたい(URLでも結構でございます)
非同期読み込みについては
http://www.play21.jp/board/formz.cgi?ac ... 7516#37482
のJustyさんの回答などを参考にしてください。
それから非同期読み込みが何に対してどれぐらい遅いのか定量的に判断しないと意味をなさないと思いますよ。
Re: 関数の呼び出し速度
Posted: 2011年10月23日(日) 23:27
by kyou.s
分かりました
関数呼び出しの負荷はあまり考慮しないことにします
ソフト屋さんの言っている画像の半透明部分というのは
あらかじめ編集して削ぎ落とすことで解決できませんか?
BGMに関してはソフト屋さんがあげてくれた関数で解決できそうです
foxさんがあげてくれたURLの非同期は画像を読み込むときなんかに使っていきたいと思います
少し、タイトルからずれますが
自分はキャラオブジェクトを作るときに新たに構造体の実体を作り出すのではなくて
いらなくなったキャラオブジェクト情報が入ったキャラ構造体の中身を入れ替えて使っています
前はスタック領域なるものを使っていたのですが
このやり方ならstaticに変えても問題ないですよね
(両方のやり方で動くし、変えたほうがいいのかって思いまして)
Re: 関数の呼び出し速度
Posted: 2011年10月24日(月) 02:40
by bitter_fox
kyou.s さんが書きました:
自分はキャラオブジェクトを作るときに新たに構造体の実体を作り出すのではなくて
いらなくなったキャラオブジェクト情報が入ったキャラ構造体の中身を入れ替えて使っています
前はスタック領域なるものを使っていたのですが
このやり方ならstaticに変えても問題ないですよね
(両方のやり方で動くし、変えたほうがいいのかって思いまして)
これもリソース的な問題でしょうか?相当節約を行ってるようですがリソース的に厳しい環境なのですか?
kyou.sさんのコンピュータのスペックが分からないのでアレですが、現代的なコンピュータを対象とするのであればそこまでの節約をする必要はないと思います。
それに、中身を入れ替えて使うとバグの温床になったりデバッグが困難になったりするので相当なことが無い限りはするべきでないと思います。
staticな変数とそうでない変数は性質が違いますので必要な性質に基づいてどちらにするかを決めてください。
両者のコストはプラマイゼロで良い所もあれば悪い所もあるといった感じでしょうか
コード:
struct Chara
{
char *name;
int imgs[16];
int x, y;
int width, height;
int hit_point, max_hit_point;
int magic_point, max_magic_point;
};
ちなみにこのようなよくある構造体が占めるサイズは4(char*) + 4*16(int[16]) + 4*8(int8個)[Byte]で100バイトとなります。(name等の実体は別、ポインタ型:4バイト,int型:4バイトとして計算)
この構造体で1KBを占めるには約10個、1MBを占めるには約10485個、1GBを占めるには約10737418個必要です。果たしてこれだけの量を同時に用いる可能性はあるでしょうか?
Re: 関数の呼び出し速度
Posted: 2011年10月24日(月) 09:05
by softya(ソフト屋)
kyou.s さんが書きました:分かりました
関数呼び出しの負荷はあまり考慮しないことにします
ソフト屋さんの言っている画像の半透明部分というのは
あらかじめ編集して削ぎ落とすことで解決できませんか?
当たり判定を内部処理で気持ち小さめにするとか手はありますが、ゲームがストリートファイターの様に手足の長いものだと別に当たり判定のデータを持たないと思うような当たり判定は出来ません。つまり、マリオ的な物とストリートファイターのようなものではアプローチが全く違うということです。
あと主人公が武器を持っていたりするとまた話は違ってきます。
kyou.s さんが書きました:少し、タイトルからずれますが
自分はキャラオブジェクトを作るときに新たに構造体の実体を作り出すのではなくて
いらなくなったキャラオブジェクト情報が入ったキャラ構造体の中身を入れ替えて使っています
前はスタック領域なるものを使っていたのですが
このやり方ならstaticに変えても問題ないですよね
(両方のやり方で動くし、変えたほうがいいのかって思いまして)
リソースに厳しくするよりはバグの混入を防ぐことを優先してください。
同じ構造体の使い回しは前のデータが残っていた場合何となく動いてバグの原因が分かりづらくなることがあります。
それと「前はスタック領域なるもの」ローカル変数のことでしょうか? 変数の寿命を理解しているなら別段問題はありませんが迂闊に使うと致命的なバグの原因になります。
Re: 関数の呼び出し速度
Posted: 2011年10月24日(月) 16:53
by kyou.s
>>foxさん
ありがとうございます
それだけの数の構造体を用意しても1MBにしかならないんですか・・・
自分は98,2000ですのでちょっと気をつけなきゃならんのかなと神経質になってました
構造体はバンバン使おうかなと思います
>>ソフト屋さん
スタックじゃなくてヒープでした…;
すいません
自分はまだまだ初心者なのでここで疑問が湧くのですが
例えば当たり判定関数に数値を渡すとき
構造体の中身を入れ替える方法ならatarihantei(chara[])こんな一文を
メイン関数に置いておけばいいですが
構造体をポンポン作り出す場合はさっきの一文だけでは対応しきれませんよね
ゲームの進行状況なんかでどの構造体を渡すかのコントロールをしなければいけませんが
どうするんでしょうか?if文と配列の添え字ですか?
Re: 関数の呼び出し速度
Posted: 2011年10月24日(月) 16:59
by softya(ソフト屋)
kyou.s さんが書きました:構造体をポンポン作り出す場合はさっきの一文だけでは対応しきれませんよね
ゲームの進行状況なんかでどの構造体を渡すかのコントロールをしなければいけませんが
どうするんでしょうか?if文と配列の添え字ですか?
基本的には構造体ポインタや構造体配列のポインタで管理できると思います。
場合によってはリスト構造なども考えられますが、どちらにしても先頭ポインタだけで管理できると思いますが。
【追記】
一般論に過ぎませんので"kyou.sさんに最適な方法は違うかも知れませんがソースコードを見ないことには何とも言えません。
Re: 関数の呼び出し速度
Posted: 2011年10月24日(月) 17:52
by ISLe
kyou.s さんが書きました:ソフト屋さんの言っている画像の半透明部分というのは
あらかじめ編集して削ぎ落とすことで解決できませんか?
例えば突起などが付いているイメージでひとつのキャラクタが複数の当たり判定用の矩形領域を持つ場合があります。
キャラクタによって当たり判定領域は固定なので、当たり判定領域はテーブルデータにして、キャラクタ構造体にはどのキャラクタなのかを識別するための番号などの情報を持たせてテーブルデータから引っ張ってくるようにするとメモリの節約にもなります。
kyou.s さんが書きました:自分はキャラオブジェクトを作るときに新たに構造体の実体を作り出すのではなくて
いらなくなったキャラオブジェクト情報が入ったキャラ構造体の中身を入れ替えて使っています
前はスタック領域なるものを使っていたのですが
このやり方ならstaticに変えても問題ないですよね
(両方のやり方で動くし、変えたほうがいいのかって思いまして)
アロケータを分離してメインロジックに影響しないようにしたら良いと思います。
Re: 関数の呼び出し速度
Posted: 2011年10月25日(火) 00:02
by kyou.s
〉〉ソフト屋さん
ソースコードを見せろということについてですが
この当たり判定を使うアクションゲーム(マリオ系)の方はまだ全く手を付けていない状態でして
ソースコードは提示できないのです
(ちなみに今迄につくったのはインベーダーやブロック崩しなどの簡易なもの)
書いてから考えてから勉強してから質問しろって話ですが
知らないことはすぐに知りたいってのが人間の欲ってもんでして…すいません
構造体ポインタをどう使うのですか?Cにこの機能があることは知っていますが
今回の例では具体的にどのように使うのでしょうか?
それとリスト構造ってのが分からなくて調べまして、自己参照構造体を紹介しているサイトが
一番、分かりやすかったのですが恐らく、ソフト屋さんの言っているリストとは無関係でしょう
先頭ポインタやリストとはなんでしょうか?
〉〉ISLeさん
テーブルデータってのが調べましたがよくわかりません
初心者の私なら当たり判定につかう情報もキャラ構造体に入れてしまいそうですが
これは間違いなのでしょうか?
最後にお書きになられた一文ですが調べたところ本能的に分からない部類のものだと感知しました
とりあえずは放置しておきたい要素に感じましたが
出来たらあけろーたの翻訳をお願いしたいです
Re: 関数の呼び出し速度
Posted: 2011年10月25日(火) 00:31
by softya(ソフト屋)
>構造体ポインタをどう使うのですか?Cにこの機能があることは知っていますが
>今回の例では具体的にどのように使うのでしょうか?
こんな風に使います。
コード:
// キャラクタ構造体の配列
char_object char1[3];
char_object char2[3];
// キャラクタ構造体配列のポインタ
char_object *pchar = char1;
char_move(pchar);
if( /*なんたら条件*/ ) {
pchar = char2;
}
リストは自己参照構造体を使ったリスト構造のことです。
http://www9.plala.or.jp/sgwr-t/c/sec15-5.html
敵など不特定多数個の物を扱うときに使います。
先頭ポインタは文字通りリストの先頭です。
ISLeさんの分も解説すると、
テーブルデータは構造体配列のことで、キャラクタ毎の当たり判定データを構造体配列に格納しておいて、当たり判定時はこのテーブルの配列番号で情報を得るという間接参照テクニックです。
アロケータ(割り当て)はメモリ管理を分離すると言う話でメモリ自体はmallocでもstaticでも構わないですが、管理モジュールに分離してメインからは細かいことは気にしなくて良くするって話ですね。
Re: 関数の呼び出し速度
Posted: 2011年10月25日(火) 01:20
by ISLe
kyou.s さんが書きました:テーブルデータってのが調べましたがよくわかりません
初心者の私なら当たり判定につかう情報もキャラ構造体に入れてしまいそうですが
これは間違いなのでしょうか?
間違いというわけではありませんが、キャラ構造体に入れてしまうと同じ種類のキャラでデータを重複して持つことになります。
当たり判定に必要なデータの一覧表(テーブル)を配列などで別に作っておいて参照すると省メモリになる上、当たり判定の実装を分離できます。
メインロジックに影響をあたえることなく好きなだけ当たり判定を調整できます。
画像サイズで当たり判定するのを貫き通すなら、余計な手間でしかないかもしれませんけど。
kyou.s さんが書きました:最後にお書きになられた一文ですが調べたところ本能的に分からない部類のものだと感知しました
とりあえずは放置しておきたい要素に感じましたが
出来たらあけろーたの翻訳をお願いしたいです
アロケータ(allocator)はアロケート(allocate)する者という意味で、メモリ等の割り当てを管理する仕組みのことです。
例えば、
struct Chara *createChara(void);
というキャラ構造体をひとつ作ってポインタを返す関数を作ります。
createChara関数の中で、新しいキャラ構造体を割り当てるメモリが配列の空き要素なのか、mallocで動的に確保しているのか、ということは呼び出し側は分かりませんし知る必要もないことです。
そして、あとからcreateChara関数の中身をどう変えようとも呼び出し側には影響しません。
Re: 関数の呼び出し速度
Posted: 2011年10月25日(火) 23:49
by kyou.s
>>ISLeさん
あぁ、なるほど…ずっと格闘ゲームを想像していましたが
同じ種類の敵が複数出てくるゲームとかのことですね…
あぁ確かにそれは便利だ メモリの節約度合は分かりませんが結構いくもんなんすかね?
クリエイトに生かさしていただきます
アケロータももっと専門用語バンバンかと思ったのですが分かりやすく教えてくれて
こちらも参考になります ありがとうございます
〉〉ソフト屋さん
ふむふむ…ポインタをですか
ソフト屋さんは前に「同じ構造体の使い回しは前のデータが残っていた場合何となく動いてバグの原因が分かりづらくなることがあります。」と仰っていましたが
ポインタの使いまわしは大丈夫なのでしょうか?(今回の例でいえばpcharポインタです)
リストはこれからみてます
Re: 関数の呼び出し速度
Posted: 2011年10月26日(水) 00:02
by softya(ソフト屋)
ポインタも構造体も使わずに管理はできませんので何らの仕組みは必要ですが、ポインタもミスすれば色々な害がありますので、どこで何をチョイスするかはプログラマの腕の見せ所ですね。
とにかく内容を書き換えたことがわかりやすくて、切り替えミスのバグが出づらい方法を常に考えておくことが重要です。