17

次のオブジェクトがあります

int [,] oGridCells;

固定の最初のインデックスでのみ使用されます

int iIndex = 5;
for (int iLoop = 0; iLoop < iUpperBound; iLoop++)
{
  //Get the value from the 2D array
  iValue = oGridCells[iIndex, iLoop];

  //Do something with iValue
}

.NET で固定の最初のインデックスの値を 1 次元配列に変換する方法はありますか (値をループする以外に)?

配列が1回だけループされている場合、コードが高速化されるとは思えません(そして、遅くなる可能性があります)。ただし、配列が頻繁に操作されている場合は、多次元配列よりも 1 次元配列の方が効率的です。

私がこの質問をする主な理由は、製品コードに使用するのではなく、それを実行できるかどうか、およびその方法を確認することです。

4

6 に答える 6

35

次のコードは、16 バイト (4 int) を 2 次元配列から 1 次元配列にコピーする方法を示しています。

int[,] oGridCells = {{1, 2}, {3, 4}};
int[] oResult = new int[4];
System.Buffer.BlockCopy(oGridCells, 0, oResult, 0, 16);

正しいバイト オフセットを指定することで、配列から 1 行だけを選択的にコピーすることもできます。この例では、3 行の 2 次元配列の中央の行をコピーします。

int[,] oGridCells = {{1, 2}, {3, 4}, {5, 6}};
int[] oResult = new int[2];
System.Buffer.BlockCopy(oGridCells, 8, oResult, 0, 8);
于 2009-04-28T11:17:56.920 に答える
3

Edit:

I realized there is a way! Granted, it's probably not worth it. Use unsafe code. Full example, showing both ways, with unsafe below:

public class MultiSingleUnsafe
{
    public static unsafe void Main(String[] a)
    {
    int rowCount = 6;
    int iUpperBound = 10;
    int [,] oGridCells = new int[rowCount, iUpperBound];

    int iIndex = rowCount - 2; // Pick a row.

    for(int i = 0; i < iUpperBound; i++)
    {
        oGridCells[iIndex, i] = i;
    }

    for (int iLoop = 0; iLoop < iUpperBound; iLoop++)
    {
        //Get the value from the 2D array
        int iValue = oGridCells[iIndex, iLoop];
        Console.WriteLine("Multi-dim array access iValue: " + iValue);
        //Do something with iValue
    }
    
    fixed(int *lastRow = &(oGridCells[iIndex,0]))
    {   
        for (int iLoop = 0; iLoop < iUpperBound; iLoop++)
        {
        int iValue = lastRow[iLoop];
        Console.WriteLine("Pointer access iValue: " + iValue);
        }
    }
    }
}

C# で多次元配列を 1 次元配列にキャストする方法がわかりません。もちろん、新しい 1 次元配列を作成してコピーすることもできます。ただし、値を複数回ループしても、パフォーマンスが向上するとは思いません。Daren が言ったように、とにかく内部的にはすべてポインタ演算です。確実にしたい場合は、プロファイルしてください。

于 2009-04-28T11:16:04.570 に答える
1

「しかし、配列が頻繁に操作されている場合は、多次元配列よりも単一次元配列の方が効率的です。」

去年の夏に正確にプロファイリングを行いましたが、2Dアレイと1Dアレイのパフォーマンスに大きな違いがないことに驚きました。

ジャグ配列のパフォーマンスはテストしていません。

于 2009-04-28T11:24:04.317 に答える
1

各配列への参照を取得することはできません。ただし、ジャグ配列を使用することはできます。

于 2009-04-28T11:20:25.213 に答える
1

I'd be suprised if it were possible: I bet oGridCells[iIndex, iLoop] is just a sort of shorthand (internally, in MSIL) for oGridCells[iIndex * iLoop], and that multidimensional arrays are syntactic sugar for this.

To answer your question: No. You will have to loop the values.

于 2009-04-28T11:14:31.717 に答える
1

これを試すことができます:

 int[,] twoD = new int[2,2];
 twoD[0, 0] = 1;
 twoD[0, 1] = 2;
 twoD[1, 0] = 3;
 twoD[1, 1] = 4;

 int[] result = twoD.Cast<int>().Select(c => c).ToArray();

結果は、データを含む整数配列になります。

1, 2, 3, 4
于 2017-08-18T03:50:22.757 に答える