2014-09-09 5 views
0

2 차원 어레이에 3 차원 어레이로 변환가 I이 바이트 배열이

byte[,] useThisDataOnly = new byte[100,150]; 

를 현재를 I 이것을 사용

foreach (int x=0,x< 100; x++) 
{ 
    foreach (int y=0,y< 150; y++) 
    { 
     useThisDataOnly [x,y] = somedata[x,y,0]; 
    } 
} 

더 빠른 방법이 있나요?

또한이 useThisDataOnly를 평면화하려고합니다 (조작하는 것이 더 빠르다고 들었습니다).

제안 사항?

+0

더 빠르고 더 실적이 좋은 것은 무엇입니까? 이 배열 크기에서는 매우 자주하지 않는 한 별 상관 없습니다. – thumbmunkeys

+0

@thumbmunkeys 안녕하세요, 시간과 의견을 보내 주셔서 감사합니다. 예, 매 초마다 이러한 배열을 많이 받게 될 것이라는 요구 사항을 받았습니다 (신음 소리가 없습니다). 나는 여기서 2 가지 질문을하고 있다고 생각한다. 내 주요 초점은 낮은 메모리 사용량에서 가능한 한 빨리 foreach를 사용하지 않고 3dim을 2dim으로 변환하는 것입니다. –

+0

안녕하세요 @AlexFarber 좋은 링크 (나와 +1)이지만 예제에서는 [,]에서 []까지를 보여줍니다. 나는 이상적으로 [,,] []에? –

답변

1

당신이 이것을 최적화하는 데 어려움을 겪고 싶지 않은 바이트는 "가장 빠르게 움직이는"색인입니다.

내가 그 의미하는 것은 : 당신과 같이 각 배열 요소에 연속 번호를 할당하는 경우 :

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"); 
     } 
    } 
} 

나는 개인적으로 어쨌든 간단하고 안전 루프를 사용하여 너무 느린 될 것이라고 생각하지 않는다,하지만 지금은 적어도 당신은 시도 몇 가지 코드가 있습니다.

+0

안녕하세요. 나는 네가하는 말을 이해하고 나에게 의미가있다. 불행히도, 나는 입력을 제어 할 수 없다. 하지만 안전하지 않은 코드 설명과 관련하여 궁금합니다. 당신은 안전하지 않은 기술을 사용하는 접근법을 암시하고 있습니까? 그렇다면 그것에 대해 조언하고 있습니까? .. 감사합니다. –

+1

@AndrewSimpson 예, 안전하지 않은 코드와 포인터를 사용할 수 있습니다.하지만 이는 어셈블리가 안전하지 않은 것으로 표시되어 보안에 영향을 미칠 수 있음을 의미합니다. 그럼에도 불구하고 볼 수 있도록 샘플 코드를 게시하겠습니다. 조금 더 빨라질 수도 있지만, 가능하지는 않습니다! –

+0

그게 너에게 좋다. 모든 시간 내 주셔서 대단히 감사합니다! –

관련 문제