Big Oは本当に重要ですか?


17

学界の最悪の場合、Big Oは他のすべてについて教えられます。スペースの複雑さ、通常のケース分析、複雑さに対する単純さなどと比較して。

特にゲームプログラミングと業界にとって、最も重要なのはなぜですか?

参照は非常に役立ちます。


Big-O =最適化。big-0が何であるかを理解するために少し時間をかけました。
AttackingHobo

12
Big-Oは「最適化」ではありません。Big-Oは、作用する要素の数が増えるにつれて、効率の観点からさまざまなアルゴリズムがどのように動作するかを示す分析形式です。詳細については、en.wikipedia.org / wiki / Big_O_notationを参照してください。
-ZorbaTHut

2
octreesとBSP / PVSを思いついた人々は、big-Oについてすべてを知っていました。最後に、重要なのはアプリケーションのパフォーマンスだけです。しかし、そこにたどり着くには、大量のデータを処理するアルゴリズムの漸近的な複雑さを含め、あらゆる方法を考慮する必要があります。
drxzcl

1
最適化のタイミングのルールを覚えておいてください:1)しないでください。2)(専門家のみ)まだしないでください。
ザラトゥストラ

まず第一に、Big Oはスペースや計算の複雑さのために使用できるため、「その他すべてのもの」は正確には真実ではありません。第二に、Big Oは通常、通常のケース分析よりも何かを計算するのがはるかに簡単であり、何か間違ったことをしているかどうかをすばやく確認するために使用されます。スプライトの描画にO(2 ^ n)時間かかる場合は、おそらく別のアルゴリズムを選択する必要があります。ソフトウェア設計により実用的なアプローチが必要な場合は、CSではなくSEの実践を検討してください。CSは本質的に理論的であり、SEはより産業に基づいています。
削除者

回答:


25

「One True Pathとは何か」に関する他のすべての質問と同様に、これらはすべてツールボックス内のツールであり、big-Oがすべてに勝る場合と、重要でない場所(tm)があります。

big-Oを気にせずに物理ソルバーを「決して」書くことはありません。心配することなく、並べ替えアルゴリズム(最小のデータセット以外)を実装することはありません。ネットワークゲームを作成している場合、ユーザーごとのパフォーマンスとネットワークトラフィックのスケーリング方法に関心があります。

ビッグOについてはあまり気にしないかもしれませんが、まあ、私は本当に時間を考えることができませんが、いくつかあると確信しています。:)ありがたいことに、ゲームで行うことのほとんどは直線的にスケーリングします。あなたはディスクからファイルを読みたいですか?ファイルサイズに直線的に比例する時間を要します(シークの一定の要因とセクターサイズの潜在的な影響を割引きます)。

ただし、エンティティリストで特定のエンティティを検索する場合はどうなりますか?これは、実行するたびに線形検索されます。世界中のすべてのエンティティに対してプレイヤーを1回見つける必要がある場合、このアプローチは、最も些細なゲームを除いてすべてを殺します。またはプレーヤーへのポインター)、プレーヤーに実際に見える他のことをする時間を与えます。

しかし、それはそれを要約していると思います。プロセッサがプレイヤーに直接表せない何かをしているときはいつでも、時間を浪費しています。プロセッサがプレーヤーに表示されるデータを計算する時間を最大化すると、WOW!プレイヤーに与えています。


8
この。コードのパフォーマンス特性を理解することが重要です。デザイナーが追加したものを予想外の方法でいつ使用するかわからないだけで、突然5つのアイテムを処理するだけでよいと思っていたコードが5000を処理し、フレームの100回pingされるようになりました。それを最適化しますか?あなたはできる?実際にどれくらい合理的ですか?プロファイルは、理由ではなく、それがどれだけ遅いかを示します。複雑さを知ることで、コードを最適化する必要があるか、別のコードに置き換える必要があるかがわかります。
JasonD

3
同意した。大学は、あなたが直面する多くの問題を処理するため、「Big-O」を教えます。あなたが「ああ、尋ねられたとき、私たちはたった5つではなくこれを無限にすることができますか?テスターは制限が嫌いです。それがトレーニングの成果です。「いいえ、できない」とだけ言ってはいけません。それから問題を解決し、「はい」と言うことができることが重要です。ゲームに検索可能な銀河が必要ですか?'問題ない'。それらの百万台を注文する必要がありますか?'問題ない'。「十分に勉強しませんでした」だけでそれをカットしません。
-Rushyo

「...の場合、big-Oについてそれほど気にしないかもしれません」入力キーを処理します。ルックアップテーブルを使用して、キーからアクションへのマッピングを一定の時間で解決するために長々とした入力システムを継承しました。(キー、アクション)ペアの配列の線形検索に切り替えても、メモリを節約し、ユーザーがフレームあたり数個以上のキーを押すことはめったにないため、パフォーマンスに影響はありませんでした。また、コードの(キー、キー、アクション)を追加できます。

ジョー、確かに、それは別の種類の懸念です。定数係数が高いO(1)か、定数係数が小さいO(n)が必要ですか?この場合、big-Oを知ることは問題ではありませんが、ソリューションが使用される状況に意味があるかどうかを判断するのに役立ちます。
ダッシュトムバン

13

私の経験則では、O(怖い)でない限り、他の問題はより適切です。

私のもう1つの経験則は、データが重要だということです。現実的なデータセットを使用してコードをプロファイリングしない限り、推測を行うだけです。

編集:もう少し詳しく説明すると、(少なくとも私の経験では)データセットのほとんどが比較的小さいため、大きなOはそれほど重要ではありません。おそらく、数百要素未満のデータ構造で作業している場合、パフォーマンスの上限は気にしません。また、リストに10万以上の要素がある場合、アルゴリズムのすべての側面を考慮する必要があります。それと、私の経験からすると、メモリはCPU速度よりも制限要因です。より高速なメモリホグアルゴリズムは、ユースケースによっては、無駄のないアルゴリズムほどではないかもしれませんが、遅いアルゴリズムです。


8

Big Oはほとんどの場合重要ですが、理論的には明らかに「悪い」アルゴリズムが実際にははるかに高速であることが判明します。

Tony Albrechtのすばらしい例をご覧くださいhttp : //seven-degrees-of-freedom.blogspot.com/2010/07/question-of-sorts.html

これは、操作のアイテムの数が非常に多く、非常に異なるアルゴリズムが高速であるか、またはダンバーアルゴリズムで十分である(またはキャッシュに収まるほど効率が優先される)ため、ゲーム開発のあらゆる場所で見つかりますのより良いアルゴリズム)。

Big Oの問題は、タスクの複雑さの一般的な指定であり、最新のターゲットハードウェアの複雑さを考慮しておらず、セットアップ時間のオーバーヘッドに関する洞察も提供しないことです。

多くの場合、最適なソリューションは2段階です。実際には、ゲーム開発者は低Oアルゴリズムに向かう傾向がありますが、開発やデバッグの時間的コストとのバランスが取れています。妥当な解決策が得られたら、常にハードウェアがタスクを処理する方法と、ハードウェアをより短時間でより多く処理する方法を検討する必要があります。


「ビッグOの問題」は、大きなデータセットサイズに比べてパフォーマンスがアルゴリズムの複雑さであることを人々が忘れているように見えることです。ゲームでは、(通常)Nの値にヒットしないため、パズルの他のピースについて心配する必要があります。2つの要素のリストがある場合、バブルソートは常にクイックソートよりも優れていると思われます。
ダッシュトムバン

7

私は、エンジンコーディングだとき、私は頻繁にのみ固定で心配です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、小さいデータセットで速く、理解しやすいことを見つけます;より興味深い/複雑なもの(例えばパトリシアトライ)は、人々が理解し維持するのが難しいですが、大きい場合は高いパフォーマンスを発揮しますデータセット。)


4

便利な場合もありますが、無関係な場合もあります。たとえば、私の最新のゲームを見てみましょう。これはSmash TVのクローンです。トップダウンゲーム、モンスターが側面から注ぐ、あなたはそれらを撃ちます。

現在、衝突を判断するための賢い方法がたくさんあります。KDtreesを使用してスペースを分割することで、攻撃できない可能性のあるモンスターに対して弾丸をテストする必要がなくなります。そして、確かに、私は賢いこともできたかもしれません。

しかし、私は怠feelingだったので、私はすべての弾丸をすべてのモンスターと比較しました。最も忙しい状況でも、コリジョンコードはゲームのCPUの60%で10%をはるかに下回っていました。Big-O:重要ではありません。

同様に、島に都市を建てる4xスタイルのゲームがあり、時には都市が破壊されました。私は賢くて、破壊された都市の収入を収入変数から差し引くことを試みたかもしれません。しかし、私はしませんでした。私は収入を一掃し、何かが変わるたびにゼロから再計算しました。CPUに関してはまったく関係ありません。

Big-Oは他のすべてのものと同じようにゲームでも重要です。つまり、重要ではなくなるまで、まったく重要ではありません。

コードを書いてください。遅すぎる場合は、プロファイルを作成します。


3

Big-O分析は重要ですが、ゲーム開発で最初に考えることはありません。ゲームの作成には多くの複雑なコードが含まれていたため、アルゴリズムの最初の基準としては常にCode Simplicityをお勧めします。複雑な簿記のアルゴリズムは時間を無駄にします。

開発中、ゲームを常に60 fpsで実行することが非常に重要だと思います。それ以下に浸るとき、最初にすることはプロファイラーを実行することです。ボトルネックを見つけたら、それを攻撃します。多くの場合、レベルデザイナーに、エリアに置くものを少なくするように(そして、そのためのツールを提供するように)コーディング以外のことをする必要があります。

時には、実際に高速化する必要のあるコードを特定します。これは楽しいエンジニアリングだと思います!これを行う機会がもっとあればいいのに。そしてもちろん、一度に1つのことを変更し、パフォーマンスを測定することを繰り返します。私が見つける典型的な問題は次のとおりです。

  1. 各フレームでnewまたはmallocを呼び出していないことを確認してください(これは常に#1の問題です)
  2. 作業の削減:レイキャストの削減、人員の削減など
  3. Big-Oアルゴリズムタイプの問題
  4. キャッシュの一貫性:分散メモリではなく配列にデータを配置します
  5. デバッグモードでSTLを使用しないでください。(そして、あなたは常にデバッグモードを動作させたい)

2

Big-O表記は、定義上漸近的な複雑さです。つまり、N(またはユーザーが持っている変数)が「非常に」大きくなったときの時間のスケールを示します。Tetradのコメント(私はこれを更新しました)について繰り返しますが、「データは重要です」。特定の状況でNが「非常に大きい」場合は重要です。Nが「非常に小さい」場合は重要ではありません。経験と実践は、「非常に大きい」と「非常に小さい」を定量化する方法を実感できます。

明らかに、常に最初にプロファイルを作成し、最後に最適化します(機能の実行可能性の調査を行っている場合を除く)。


1

ソフトウェアにおけるBig-Oの重要性はO(N 2)です。Nが大きくなるにつれて、適切なアルゴリズムを持つことの重要性はさらに大きくなります。:)


それは、そのアルゴリズムが呼び出される頻度に依存しませんか?
ボボボボ

ある程度まで。ただし、実行に3日かかる場合は、1回だけ呼び出しても問題ないでしょう。:)
カイロタン

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が非常に小さい場合、アルゴリズム間の違いはほとんど無視できます。


0

参考文献はありませんが、Big Oは問題と議論を分析する際に少なくとも知っておくと便利です。一方、もちろん、O(log n)バージョンがO(n)バージョンよりもOに深く関与している場合、それは意味のない比較です。そして、すべてと同様に、常にトレードオフがあります。スペースの複雑さが問題になる可能性がありますが、一般的にはOでも表現できます。通常のケース分析...そうではありません。外れ値も急上昇させたくないためです。私の意見では、複雑さに対する単純さは、速度がほぼ常に問題であるため、ゲーム開発では比較的役に立たないので、単純化が高速化につながる場合を除き(ただし、それはあなたの複雑なケースが間違った理由で間違っていたことを意味します)速度を優先してウィンドウの外に。しかし、Big Oは間違いなく便利です。


0

あなたはゲーム機能やゲームの様相をプロトタイプとき、あなたはそれを最適化する心配はならないすべてで

それをプロトタイピングし、その機能の特異性について学習する過程で、必要な最適化は明らかになり、ほとんどの場合、第2の性質のような最終設計に組み込まれます。

汗をかかないでください。


「ゲーム機能またはゲームの側面をプロトタイプ化するとき、最適化についてまったく心配する必要はありません。」これは時々当てはまりますが、常にそうとは限りません。Dead Risingのような特定のゲームは、コアゲームメカニック(リアルタイムで数百のゾンビ)を実現するために高速実行に依存しています。

ゲーム開発の何パーセントがプロトタイピングされていますか?最終的には何かを出荷したいですよね?
ダッシュトムバン

0

それはすべてとすべてではありません。ただし、パフォーマンスヒットを引き起こす可能性のある明らかな問題を整理するのに役立ちます。O(log n)時間で同じことができるのに、なぜO(n ^ 2)時間で何かを使用するのですか?

市場は速度の問題に最も気づく市場であるため、他のほとんどの業界よりもゲームに適用されると思います。ワードプロセッサを使用している人は、アクションXを実行するのに0.5秒の遅延があるかどうかは気にしませんが、ゲーマーはおそらく「ゲームYが非常に遅いため、アクションZを実行するには時間がかかります」と思うでしょう。


0

ゲーム(および他のほとんどの)開発では、ループごとに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)(以上)の数値計算アルゴリズム(ユーザーのバッグの検索など)をスクリプトに記述させないでください。代わりに、コードに組み込み関数を作成します。


1
コード例は両方ともO(n)です。Big-Oの議論は、「ループごとに1つの余分な操作」とは関係なく、「すべてのループの反復ごとにすべてを1回余分に検索」します。
ダッシュトムバン

-2

現実の世界では、生のパフォーマンスのみが重要です。現在、アルゴリズムのBig-Oは何を使用するかを示す最初の指標として役立つかもしれませんが、ハードウェアによっては実装がひどく非効率的である場合があります。たとえば、線形メモリアクセスと分岐なしを取得するため、線形検索を実行すると、バイナリ検索よりも高速になることがよくあります。

また、マルチスレッドプラットフォームとアーキテクチャの現在の方向性のため、Big-Oは、アルゴリズムの方法も考慮せずに、操作ごとのメモリまたはデータタッチの垂直スケーラビリティのみを考慮しているため、多くの重要性を失っています。より多くのスレッドでスケーリングします。


3
これは誤りです。BigO表記は、線形アルゴリズムとまったく同じ並列アルゴリズムの上限を示すために使用されます。ビッグOは、ほら同時読み取り/書き込み同時のアーキテクチャなどのためにあなたもクレイジーでO(1)で並べ替えのようなもののn ^ 2つのプロセッサを行うことができます使用することができます
デイヴィッド・ヤング

デビッド、実生活の例はありますか?つまり、人々のグループが持ち運ぶことができるリンゴの数をBig-Oにすることもできますが、それは使用済みまたは有用であることを意味するものではありません。私の経験から、ほとんどの場合、gamedevは成長関数ではなく生のパフォーマンスに基づいて(並列)アルゴリズムを選択します。
ジャスパーベッカーズ

3
「n ^ 2プロセッサでO(1)を並べ替える」どのような方法で問題を切り分けても、リソース使用量はまだO(n ^ 2)であるため、このOの使用は誤解を招くと一般的に感じています。スレッドの数が多いということは、1秒あたりのCPUサイクル数が多いことを意味するだけではありません。
リチャードファビアン

n ^ 2プロセッサでのO(1)でのソートは最良の例ではありません。このタイプのBig-O表記は、おそらく学界で最もよく見られます。このようなものcs.bu.edu/~best/crs/cs551/homeworks/hw1/pram.htmlより現実的な並列アルゴリズムでは、log(n)プロセッサーを使用できます。この種のものは、GPU処理またはスーパーコンピューティングに何百ものコアが利用できる場合のオーバーロードに適しています。
デビッドヤング

過負荷ではなく、オフロードを意味します。元のコメントはもう編集できません。
デビッドヤング
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.