티스토리 뷰

목차

    반응형

    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)

    반응형