[英]convert 3 dimensional array to a 2 dimensional array
我有這個字節數組:
byte[,,] somedata = new byte[100,150,3];
~somedata is now populated by an external input.
我只想在其中使用這些值:
byte[,] useThisDataOnly = new byte[100,150];
目前,我使用這個:
foreach (int x=0,x< 100; x++)
{
foreach (int y=0,y< 150; y++)
{
useThisDataOnly [x,y] = somedata[x,y,0];
}
}
有沒有一種更快的方法呢?
另外,我將把這個useThisDataOnly扁平化(據我所知,它的處理速度更快)。
有什么建議么?
優化這一點的困難在於,要忽略的字節位於最“快速移動”的索引中。
我的意思是:如果像這樣給每個數組元素分配連續的數字:
byte[,,] source = new byte[100, 150, 3];
for (int i = 0, n = 0; i < 100; ++i)
for (int j = 0; j < 150; ++j)
for (int k = 0; k < 3; ++k, ++n)
source[i, j, k] = unchecked ((byte)n);
如果按展平的順序打印內容,將得到0..255重復。
然后,您排除最終尺寸:
for (int i = 0; i < 100; ++i)
for (int j = 0; j < 150; ++j)
dest[i, j] = source[i, j, 0];
如果按展平的順序打印結果,將得到:
0, 3, 6, 9, 12, 15, ...
因此,您可以看到為了將輸入轉換為輸出,您需要占用每個第三個字節,但是不幸的是,沒有快速的方法可以做到這一點。
但是,如果您能夠要求創建的數組首先要省略索引:
byte[,,] source = new byte[3, 100, 150];
那么您將可以使用Buffer.BlockCopy()
。
我猜這不是一個選擇-否則,手動編碼循環可能是最快的方法,而無需訴諸不安全的代碼。
不安全的代碼
這是使用不安全的代碼和指針的方法。 這甚至可能無法使其更快,因此在選擇執行此操作之前,您需要(a)確保執行簡單的方法確實太慢,並且(b)使用Stopwatch
進行發布構建的一些謹慎時機以確保確實值得使用不安全的代碼。
還應注意使用不安全代碼的弊端! 不安全的代碼需要提升的權限,並且可能會導致您的程序由於低級C ++風格的野生指針錯誤而崩潰!
using System;
using System.Diagnostics;
namespace Demo
{
internal static class Program
{
static void Main()
{
byte[,,] source = new byte[100, 150, 3];
for (int i = 0, n = 0; i < 100; ++i)
for (int j = 0; j < 150; ++j)
for (int k = 0; k < 3; ++k, ++n)
source[i, j, k] = unchecked ((byte)n);
byte[,] dest1 = new byte[100, 150];
byte[,] dest2 = new byte[100, 150];
for (int i = 0; i < 100; ++i)
for (int j = 0; j < 150; ++j)
dest1[i, j] = source[i, j, 0];
unsafe
{
fixed (byte* sp = source)
fixed (byte* dp = dest2)
{
byte* q = dp;
byte* p = sp;
for (int i = 0; i < 100*150; ++i)
{
*q++ = *p;
p += 3;
}
}
}
for (int i = 0; i < 100; ++i)
for (int j = 0; j < 150; ++j)
Trace.Assert(dest1[i, j] == dest2[i, j], "Arrays should be identical");
}
}
}
我個人認為使用簡單,安全的循環不會太慢,但是現在至少您可以嘗試一些代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.