본문 바로가기
C++ 200제/코딩 IT 정보

C# byte 배열 빠르게 합치기 (바이트 array)

by vicddory 2017. 7. 10.

C# byte 배열 빠르게 합치기 (바이트 array)


C#에서 바이트 배열 합치기를 시도할 때, System.Buffer.BlockCopy가 System.Array.Copy보다 빠릅니다. 아래는 10 바이트 배열 3개를 1백만 번 반복한 결과로 함수의 수행 시간을 측정한 결과입니다.


바이트 배열 : System.Array.Copy - 0.2187556초

바이트 배열 : System.Buffer.BlockCopy - 0.1406286초

IEnumerable<byte> : C# yield operator - 0.0781270초

IEnumerable<byte> : LINQ's Concat<> - 0.0781270초


byte 배열 크기를 100개로 늘리고 다시 테스트한 결과는 아래.


바이트 배열 : System.Array.Copy - 0.2812554초

바이트 배열 : System.Buffer.BlockCopy - 0.2500048초

IEnumerable<byte> : C# yield operator - 0.0625012초

IEnumerable<byte> : LINQ's Concat<> - 0.0781265초

byte 배열 크기를 1,000개로 늘리고 다시 테스트한 결과는 아래.


바이트 배열 : System.Array.Copy - 1.0781457초

바이트 배열 : System.Buffer.BlockCopy - 1.0156445초

IEnumerable<byte> : C# yield operator - 0.0625012초

IEnumerable<byte> : LINQ's Concat<> - 0.0781265초


마지막으로 배열 크기를 1백만으로 늘리고 복사 과정을 4,000번 반복한 결과는 아래.


바이트 배열 : System.Array.Copy - 13.4533833초

바이트 배열 : System.Buffer.BlockCopy - 13.1096267초

IEnumerable<byte> : C# yield operator - 0초

IEnumerable<byte> : LINQ's Concat<> - 0초


즉, 새로운 바이트 배열이 필요하면,


1
2
3
4
5
byte[] rv = new byte[a1.Length + a2.Length + a3.Length];
 
System.Buffer.BlockCopy(a1, 0, rv, 0, a1.Length);
System.Buffer.BlockCopy(a2, 0, rv, a1.Length, a2.Length);
System.Buffer.BlockCopy(a3, 0, rv, a1.Length + a2.Length, a3.Length);
cs


만약 IEnumerable<byte>을 사용하면 LINQ의 Concat<>을 사용할 수 있습니다. yield 보다 약간 느리지만, 더 간결합니다.


1
IEnumerable<byte> rv = a1.Concat(a2).Concat(a3);
cs


C# byte 배열 빠르게 합치기 (바이트 array)[C# byte 배열 빠르게 합치기 (바이트 array)]


닷넷 3.5를 사용할 경우 System.Buffer.BlockCopy()를 아래처럼 사용할 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
private byte[] Combine(params byte[][] arrays)
{
    byte[] rv = new byte[arrays.Sum(a => a.Length)];
    int offset = 0;
 
    foreach (byte[] array in arrays) {
        System.Buffer.BlockCopy(array, 0, rv, offset, array.Length);
        offset += array.Length;
    }
    return rv;
}
cs


참고 - 위의 블록을 사용하려면 맨 위에 다음과 같은 네임 스페이스를 추가해야 합니다.


using System.Linq;


마지막으로, 1백만 개 크기의 byte 배열을 만들고 4,000번 반복 테스트를 했습니다. 중간에 전체 데이터를 확인하는 루틴을 넣었죠. 결과는 아래와 같습니다.


바이트 배열 : System.Array.Copy - 78.20550510초

바이트 배열 : System.Buffer.BlockCopy - 77.89261900초

IEnumerable<byte> : C# yield operator - 551.7150161초

IEnumerable<byte> : LINQ's Concat<> - 448.1804799초


이 포스트의 핵심은 데이터 생성과 사용의 효율성을 이해하는 것입니다. 단순히 기능이 완성되었다는 것을 넘어 효율적으로 구성되었는지를 확인해야 하죠.


출처 - 스택 오버플로우

C# byte 배열 빠르게 합치기 (바이트 array)

댓글