[解決済み] ネストされたループに代わるより高速な方法?
質問
数字の組み合わせのリストを作成する必要があります。数字は非常に小さいので、私は使用することができます
byte
ではなく
int
. しかし、それは可能なすべての組み合わせを得るために、多くのネストされたループを必要とします。もっと効率的な方法はないものかと考えています。これまでのコードは以下の通りです。
var data = new List<byte[]>();
for (byte a = 0; a < 2; a++)
for (byte b = 0; b < 3; b++)
for (byte c = 0; c < 4; c++)
for (byte d = 0; d < 3; d++)
for (byte e = 0; e < 4; e++)
for (byte f = 0; f < 3; f++)
for (byte g = 0; g < 3; g++)
for (byte h = 0; h < 4; h++)
for (byte i = 0; i < 2; i++)
for (byte j = 0; j < 4; j++)
for (byte k = 0; k < 4; k++)
for (byte l = 0; l < 3; l++)
for (byte m = 0; m < 4; m++)
{
data.Add(new [] {a, b, c, d, e, f, g, h, i, j, k, l, m});
}
のようなものを使うことを検討していました。
BitArray
のようなものを使おうと思ったのですが、どのように組み込めばいいのかわかりません。
何か推奨事項があれば、非常にありがたいです。あるいは、おそらくこれが私が望むことを行う最速の方法でしょうか?
EDIT いくつかの簡単なポイント(そして、私は元の投稿にこれらを入れていないことを申し訳ありません)。
- 数字とその順序 (2, 3, 4, 3, 4, 3, 3 など) は非常に重要なので、次のようなソリューションを使用します。 LINQを使用した順列の生成 のようなソリューションを使用しても、各「列」の最大値が異なるため、役に立ちません。
- 私は数学者ではないので、「並べ換え」や「組み合わせ」といった専門用語を正しく使っていなければ申し訳ありません :)
- I する は、これらの組み合わせのすべてを一度に入力する必要があります - インデックスに基づいて、1 つまたは別のものを取得することはできません。
-
使用方法
byte
を使用する方がint
, I 保証 です。また、67m以上の配列はint型よりもbyte型の方がメモリ使用量に優れています。 - ここでの私の最終的な目標は、ネストされたループのより速い代替品を探すことです。
-
並列プログラミングを使うことも考えましたが、私が達成しようとしていることの反復的な性質のために、うまくやる方法を見つけることができませんでした(たとえ
ConcurrentBag
を使っても) うまくいく方法が見つかりませんでした。)
結論
Caramirielがループの時間を短縮する良いマイクロ最適化を提供してくれたので、その答えを正解としてマークしました。Eric も、List を事前に割り当てる方が高速であると述べています。しかし、現段階では、ネストされたループが実際にこれを行う最速の方法であるようです(気が滅入りますね!)。
で私がベンチマークしようとしていたことを正確に試したい場合は、次のようになります。
StopWatch
を使用する場合、各ループで 4 つまでカウントする 13 ループで行ってください - リストの行数は約 67m 以上になります。私のマシン (i5-3320M 2.6GHz) では、最適化されたバージョンを実行するのに、約 2.2 秒かかりました。
どのように解決するのですか?
注意:あなた自身のソリューションを開発している間は、おそらくこの種のコードは必要ないでしょう。これは非常に特殊な状況でのみ使用できますし、使用すべきです。読みやすさはしばしば速度よりも重要です。
構造体のプロパティを利用し、あらかじめ構造体を割り当てることができます。下のサンプルでは一部レベルを切っていますが、具体的な内容はおわかりになると思います。オリジナル(リリースモード)より5〜6倍程度高速に動作します。
ブロックが
struct ByteBlock
{
public byte A;
public byte B;
public byte C;
public byte D;
public byte E;
}
ループのことです。
var data = new ByteBlock[2*3*4*3*4];
var counter = 0;
var bytes = new ByteBlock();
for (byte a = 0; a < 2; a++)
{
bytes.A = a;
for (byte b = 0; b < 3; b++)
{
bytes.B = b;
for (byte c = 0; c < 4; c++)
{
bytes.C = c;
for (byte d = 0; d < 3; d++)
{
bytes.D = d;
for (byte e = 0; e < 4; e++)
{
bytes.E = e;
data[counter++] = bytes;
}
}
}
}
}
リストに追加するたびに新しいリストを確保しないので、より高速になります。また、このリストを作成しているので、他のすべての値 (a,b,c,d,e) への参照が必要です。各値はループ内で一度だけ変更されると仮定できるので、そのように最適化することができます(データの局所性)。
副作用のコメントも読んでください。
回答を編集して
T[]
の代わりに
List<T>
.
関連
-
[解決済み】コンパイルエラー「未割り当てのローカル変数を使用しています」が発生したのはなぜですか?
-
[解決済み】ここで「要求URIに一致するHTTPリソースが見つかりませんでした」となるのはなぜですか?
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み] エンティティタイプ <type> は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】プロジェクトビルド時のエラー。エディタでスクリプトにコンパイルエラーがあるため、Playerのビルドにエラーが発生する
-
[解決済み】取り消せないメンバはメソッドのように使えない?
-
[解決済み】IntPtrとは一体何なのか?
-
[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?
-
[解決済み】スレッド終了またはアプリケーションの要求により、I/O操作が中断されました。
-
[解決済み] リストの要素のすべての可能な組み合わせを得るには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】ここで「要求URIに一致するHTTPリソースが見つかりませんでした」となるのはなぜですか?
-
[解決済み] 保護レベルによりアクセス不能になりました。
-
[解決済み】トランスポート接続からデータを読み取れない:既存の接続は、リモートホストによって強制的に閉じられました。
-
[解決済み】値が期待した範囲に収まらない
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み】Entity FrameworkからのSqlException - セッション内で他のスレッドが動作しているため、新しいトランザクションは許可されません。
-
[解決済み】Moqを使用してメソッド呼び出しを検証する
-
[解決済み】5.7.57 SMTP - MAIL FROMエラー時に匿名メールを送信するためにクライアントが認証されない
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する
-
[解決済み] C#の多次元配列と配列の配列の違いは何ですか?