学界の最悪の場合、Big Oは他のすべてについて教えられます。スペースの複雑さ、通常のケース分析、複雑さに対する単純さなどと比較して。
特にゲームプログラミングと業界にとって、最も重要なのはなぜですか?
参照は非常に役立ちます。
学界の最悪の場合、Big Oは他のすべてについて教えられます。スペースの複雑さ、通常のケース分析、複雑さに対する単純さなどと比較して。
特にゲームプログラミングと業界にとって、最も重要なのはなぜですか?
参照は非常に役立ちます。
回答:
「One True Pathとは何か」に関する他のすべての質問と同様に、これらはすべてツールボックス内のツールであり、big-Oがすべてに勝る場合と、重要でない場所(tm)があります。
big-Oを気にせずに物理ソルバーを「決して」書くことはありません。心配することなく、並べ替えアルゴリズム(最小のデータセット以外)を実装することはありません。ネットワークゲームを作成している場合、ユーザーごとのパフォーマンスとネットワークトラフィックのスケーリング方法に関心があります。
ビッグOについてはあまり気にしないかもしれませんが、まあ、私は本当に時間を考えることができませんが、いくつかあると確信しています。:)ありがたいことに、ゲームで行うことのほとんどは直線的にスケーリングします。あなたはディスクからファイルを読みたいですか?ファイルサイズに直線的に比例する時間を要します(シークの一定の要因とセクターサイズの潜在的な影響を割引きます)。
ただし、エンティティリストで特定のエンティティを検索する場合はどうなりますか?これは、実行するたびに線形検索されます。世界中のすべてのエンティティに対してプレイヤーを1回見つける必要がある場合、このアプローチは、最も些細なゲームを除いてすべてを殺します。またはプレーヤーへのポインター)、プレーヤーに実際に見える他のことをする時間を与えます。
しかし、それはそれを要約していると思います。プロセッサがプレイヤーに直接表せない何かをしているときはいつでも、時間を浪費しています。プロセッサがプレーヤーに表示されるデータを計算する時間を最大化すると、WOW!プレイヤーに与えています。
私の経験則では、O(怖い)でない限り、他の問題はより適切です。
私のもう1つの経験則は、データが重要だということです。現実的なデータセットを使用してコードをプロファイリングしない限り、推測を行うだけです。
編集:もう少し詳しく説明すると、(少なくとも私の経験では)データセットのほとんどが比較的小さいため、大きなOはそれほど重要ではありません。おそらく、数百要素未満のデータ構造で作業している場合、パフォーマンスの上限は気にしません。また、リストに10万以上の要素がある場合、アルゴリズムのすべての側面を考慮する必要があります。それと、私の経験からすると、メモリはCPU速度よりも制限要因です。より高速なメモリホグアルゴリズムは、ユースケースによっては、無駄のないアルゴリズムほどではないかもしれませんが、遅いアルゴリズムです。
Big Oはほとんどの場合重要ですが、理論的には明らかに「悪い」アルゴリズムが実際にははるかに高速であることが判明します。
Tony Albrechtのすばらしい例をご覧ください:http : //seven-degrees-of-freedom.blogspot.com/2010/07/question-of-sorts.html
これは、操作のアイテムの数が非常に多く、非常に異なるアルゴリズムが高速であるか、またはダンバーアルゴリズムで十分である(またはキャッシュに収まるほど効率が優先される)ため、ゲーム開発のあらゆる場所で見つかりますのより良いアルゴリズム)。
Big Oの問題は、タスクの複雑さの一般的な指定であり、最新のターゲットハードウェアの複雑さを考慮しておらず、セットアップ時間のオーバーヘッドに関する洞察も提供しないことです。
多くの場合、最適なソリューションは2段階です。実際には、ゲーム開発者は低Oアルゴリズムに向かう傾向がありますが、開発やデバッグの時間的コストとのバランスが取れています。妥当な解決策が得られたら、常にハードウェアがタスクを処理する方法と、ハードウェアをより短時間でより多く処理する方法を検討する必要があります。
私は、エンジンコーディングだとき、私は頻繁にのみ固定で心配ですn
私はすでに受信オブジェクトの数を制限する空間のパーティションを持っている:update()
、physics()
、およびrender()
約それらの画面上とその周辺地域に。通常、最大バッチサイズはゲームごとにかなり明確に定義されていますが、常に計画よりも少し大きくなります。
この場合、私は定数因子乗数と低次項に関心があるので、私はビッグOにあまり関心がありません。a*n^2 + b*n + c
(のようなO(n^2)
)ランタイムを持つ関数の場合、私は多くの場合、を減らしa
、場合によっては排除することにずっと関心がありc
ます。セットアップまたはティアダウンのコストc
は、小さなものに対して比例的に大きくなる場合がありますn
。
ただし、これはbig-O(またはより具体的にはbig-theta)が優れたコードの匂い指標であると言うことではありません。参照してくださいO(n^4)
どこか、またはさらに悪いO(k^n)
幾何学的な時間、そしてあなたが他のオプションを検討しているようにすることの時間を。
私は一般に、データ作成ツールを扱っているときに、big-Oの最適性とフープをジャンプして、big-Oの低いアルゴリズムを見つけることをはるかに心配しています。一般に、特定のレベル/ストリーミングエリア内のオブジェクトの数は明確に定義されていますが、ゲーム全体のオブジェクト/アートアセット/構成ファイルなどの総数はそうでない場合があります。また、はるかに大きい数です。パラレルデータメイクを実行していても、jam data-clean && jam data
サイクルを実行するのに1分ほど待機します(コンソール用のデータメイクには数時間かかることがありますが、ほとんどが小さなハンドヘルドゲームです)。
具体的な例を挙げると、これは、8x8 256色タイルをストリーミングするバックグラウンドタイルストリーミングアルゴリズムでは本当に手に負えなくなりました。バックグラウンドの「レイヤー」間でストリーミングバッファーを共有すると便利です。同じバッファーを共有する特定のレベルで最大6つまで使用できます。問題は、必要なバッファーのサイズの推定が、6つのレイヤーすべての可能な位置に基づいていることです-そして、それらが素数の幅/高さ/スクロールレートである場合、すぐに徹底的な検索を開始します-近づき始めるO(6^numTiles)
-これは多くの場合、「宇宙が存在するよりも長い」カテゴリにあります。幸いなことに、ほとんどの場合は2〜3層ですが、それでも30分以上の実行時間です。現時点では、これらの可能性の非常に小さなサブセットをサンプリングし、設定された時間が経過するまで(または小さな二重層構成で発生する可能性のあるタスクを完了するまで)粒度を増やします。間違っていることが証明された頻度に関する以前の統計に基づいて、この推定値を少し上げてから、適切な測定のために余分なパディングを少し追加します。
もう1つの楽しい例:しばらく前のPCゲームで、リードエンジニアがスキップリストを使用してしばらく実験しました。メモリのオーバーヘッドは、より多くのキャッシュ効果を引き起こします。これにより、全体に一種の非定数乗数が追加されますn
。ただし、検索が頻繁に行われるより大きなソート済みリストの場合は、利点があります。
(私はしばしば、素朴なアルゴリズムが大きいO、小さいデータセットで速く、理解しやすいことを見つけます;より興味深い/複雑なもの(例えばパトリシアトライ)は、人々が理解し維持するのが難しいですが、大きい場合は高いパフォーマンスを発揮しますデータセット。)
便利な場合もありますが、無関係な場合もあります。たとえば、私の最新のゲームを見てみましょう。これはSmash TVのクローンです。トップダウンゲーム、モンスターが側面から注ぐ、あなたはそれらを撃ちます。
現在、衝突を判断するための賢い方法がたくさんあります。KDtreesを使用してスペースを分割することで、攻撃できない可能性のあるモンスターに対して弾丸をテストする必要がなくなります。そして、確かに、私は賢いこともできたかもしれません。
しかし、私は怠feelingだったので、私はすべての弾丸をすべてのモンスターと比較しました。最も忙しい状況でも、コリジョンコードはゲームのCPUの60%で10%をはるかに下回っていました。Big-O:重要ではありません。
同様に、島に都市を建てる4xスタイルのゲームがあり、時には都市が破壊されました。私は賢くて、破壊された都市の収入を収入変数から差し引くことを試みたかもしれません。しかし、私はしませんでした。私は収入を一掃し、何かが変わるたびにゼロから再計算しました。CPUに関してはまったく関係ありません。
Big-Oは他のすべてのものと同じようにゲームでも重要です。つまり、重要ではなくなるまで、まったく重要ではありません。
コードを書いてください。遅すぎる場合は、プロファイルを作成します。
Big-O分析は重要ですが、ゲーム開発で最初に考えることはありません。ゲームの作成には多くの複雑なコードが含まれていたため、アルゴリズムの最初の基準としては常にCode Simplicityをお勧めします。複雑な簿記のアルゴリズムは時間を無駄にします。
開発中、ゲームを常に60 fpsで実行することが非常に重要だと思います。それ以下に浸るとき、最初にすることはプロファイラーを実行することです。ボトルネックを見つけたら、それを攻撃します。多くの場合、レベルデザイナーに、エリアに置くものを少なくするように(そして、そのためのツールを提供するように)コーディング以外のことをする必要があります。
時には、実際に高速化する必要のあるコードを特定します。これは楽しいエンジニアリングだと思います!これを行う機会がもっとあればいいのに。そしてもちろん、一度に1つのことを変更し、パフォーマンスを測定することを繰り返します。私が見つける典型的な問題は次のとおりです。
Big-Oは単なるガイドラインであり、アルゴリズムに期待できる大まかなパフォーマンスと、データセットのサイズを大きくしたときにパフォーマンスがどのように拡大するかを示すものです。Big-Oに関しては、次の2つのことを覚えておく必要があります。
1)ほとんど同じことを行う2つのアルゴリズムがあり、1つはより良いOを持っている場合、おそらくその1つに行くべきです(明らかに)
2)Big Oは漸近解析に関係しています。Big-O は、nが大きい場合にのみ実際に機能します。たとえば、O(n)アルゴリズムのパフォーマンスは、n が小さい場合の O(n ^ 2)アルゴリズムと非常によく似ています。あなたは頂点ごとのn ^ 2の操作を必要とするアルゴリズムについて話しますが、N = 2またはn = 3の場合は、そこではありません O(N ^ 2)のアルゴリズムとの大きな違いは、(4と9のops RESP服用)とO(n)one(2および3 opsそれぞれ)。ただし、n = 9の場合、O(n ^ 2)アルゴリズムの操作が81回、O(n)アルゴリズムの操作が9回だけになります(大きな違いです)。n= 100の場合、 100オペレーション対10000の話-これははるかに大きな違いです。
そのため、常にその観点からBig-Oを考慮する必要があります。nが大きくなるにつれて最悪の場合のパフォーマンスに基づい て同じことを行うアルゴリズムを比較することを意味します。nが非常に小さい場合、アルゴリズム間の違いはほとんど無視できます。
参考文献はありませんが、Big Oは問題と議論を分析する際に少なくとも知っておくと便利です。一方、もちろん、O(log n)バージョンがO(n)バージョンよりもOに深く関与している場合、それは意味のない比較です。そして、すべてと同様に、常にトレードオフがあります。スペースの複雑さが問題になる可能性がありますが、一般的にはOでも表現できます。通常のケース分析...そうではありません。外れ値も急上昇させたくないためです。私の意見では、複雑さに対する単純さは、速度がほぼ常に問題であるため、ゲーム開発では比較的役に立たないので、単純化が高速化につながる場合を除き(ただし、それはあなたの複雑なケースが間違った理由で間違っていたことを意味します)速度を優先してウィンドウの外に。しかし、Big Oは間違いなく便利です。
あなたはゲーム機能やゲームの様相をプロトタイプとき、あなたはそれを最適化する心配はならないすべてで。
それをプロトタイピングし、その機能の特異性について学習する過程で、必要な最適化は明らかになり、ほとんどの場合、第2の性質のような最終設計に組み込まれます。
汗をかかないでください。
ゲーム(および他のほとんどの)開発では、ループごとに1つの追加操作が実行されます。
for (int i = 0; i < array.length; i ++) { /* ... */ }
対
for (int i = 0, l = array.length; i < l; i ++) { /* ... */ }
最近のほとんどのゲームには物理学があり、n体シミュレーションの問題が見つかります。単純なアルゴリズムでは、O(n ^ 2)ですが、O(n log n)にする最適化があります(ただし、精度は多少犠牲になります)。
重力や粒子の相互作用をプログラミングしているわけではありませんが、他の場所に依存して移動する(ゾンビの)軍隊のチーム行動についてはどうでしょう(より具体的な言葉で言うと、群がっている)。
従来の衝突検出アルゴリズムでは、時間の複雑さはn-bodyのようにO(n ^ 2)です。ただし、より良い方法があります。同じパーツ内のオブジェクトのみが衝突検出されるように、ワールドを多くの小さなパーツに分離します。http://www.videotutorialsrock.com/opengl_tutorial/collision_detection/text.phpを参照してください。
ゲームがスクリプト可能な場合は、スクリプトでO(n ^ 2)(以上)の数値計算アルゴリズム(ユーザーのバッグの検索など)をスクリプトに記述させないでください。代わりに、コードに組み込み関数を作成します。
現実の世界では、生のパフォーマンスのみが重要です。現在、アルゴリズムのBig-Oは何を使用するかを示す最初の指標として役立つかもしれませんが、ハードウェアによっては実装がひどく非効率的である場合があります。たとえば、線形メモリアクセスと分岐なしを取得するため、線形検索を実行すると、バイナリ検索よりも高速になることがよくあります。
また、マルチスレッドプラットフォームとアーキテクチャの現在の方向性のため、Big-Oは、アルゴリズムの方法も考慮せずに、操作ごとのメモリまたはデータタッチの垂直スケーラビリティのみを考慮しているため、多くの重要性を失っています。より多くのスレッドでスケーリングします。