2010-03-27 5 views
6

바이트 배열에서 여러 바이트를 제거하는 방법은 무엇입니까?처음 16 바이트를 제거 하시겠습니까?

+4

최근에 많은 질문이 제기되었지만, 최근에 많은 문제가 발생했습니다. 제목을 설명하는 데별로 도움이되지 않는 한 문장의 질문으로 구분됩니다. 지금까지 최선의 방법은 그것을하지 않는 것입니다.배열을 취하는 많은 메소드는 오프셋과 길이를 갖는 오버로드를가집니다. 전용 클래스도 있습니다 : ArraySegment . 그것이 당신의 질문에서 당신에게 확실히 불분명한지 여부. 아마도 그렇지 않습니다. –

답변

24

편집 : nobugz의 코멘트 (및 리드 Copsey의 대답은) 언급으로 당신이 실제로 바이트 배열로 결과가 필요하지 않은 경우, 당신은 ArraySegment<T>를 사용하여 조사한다 :

그렇지 않으면
ArraySegment<byte> segment = new ArraySegment<byte>(full, 16, full.Length - 16); 

, 복사가됩니다 필요한 - 배열은 항상 고정 크기이므로 기존 배열에서 처음 16 바이트를 "제거"할 수 없습니다. 대신, 더 작은 새 배열을 만들어 관련 데이터를 복사해야합니다.

자크의 제안은 비 LINQ 접근 방식에 적합한 라인을 따라이지만, (이 이미 원래의 배열이 긴 적어도 16 바이트 알고 가정) 간단하게 만들 수 있습니다 :

byte[] newArray = new byte[oldArray.Length - 16]; 
Buffer.BlockCopy(oldArray, 16, newArray, 0, newArray.Length); 

또는

byte[] newArray = new byte[oldArray.Length - 16]; 
Array.Copy(oldArray, 16, newArray, 0, newArray.Length); 

내가 의심Buffer.BlockCopy은 약간 빠른 것입니다,하지만 난 확실히 모른다.

관련된 배열이 큰 경우 LINQ 방식보다 훨씬 효율적일 수 있습니다. LINQ 방식을 사용하면 각 바이트가 반복기에서 개별적으로 반환되고 중간 복사본이 만들어 지도록 할 수 있습니다 방법은 List<T>에 항목을 추가 할 때 주기적으로 배킹 배열을 늘려야 함). 분명히 미세 최적화는하지 않지만이 코드 비트가 성능 병목이면 을 확인하십시오.을 확인하십시오.

편집 : 나는 세 가지 접근 방식 중 매우 빠르고 "더러운"벤치 마크를 실행했습니다. 나는 Buffer.BlockCopyArray.Copy을 구별 할 수있는 벤치 마크를 믿지 않습니다. 그들은 거의 가깝습니다. 그러나 LINQ 방식은 100 배 이상 느립니다.

랩톱에서 10,000 요소의 바이트 배열을 사용하면 LINQ를 사용하여 40,000 개의 복사본을 수행하는 데 거의 10 초가 걸렸습니다. 위의 접근 방식은 같은 양의 작업을 수행하는 데 약 80ms가 걸렸습니다. 반복 횟수를 4 백만으로 늘렸고 여전히 약 7 초 밖에 걸리지 않았습니다. 분명히 마이크로 벤치 마크 주변의 일반적인주의 사항이 적용되지만, 이것은 꽤 중요한 차이입니다. 이 성능 :)에 중요한 코드 경로에있는 경우

은 확실히 위의 방법을 사용

+0

+1, 큰 배열의 경우 버퍼링이 훨씬 효율적입니다. –

+0

바이트 배열과 함께 사용할 때 Buffer.BlockCopy와 Array.Copy의 차이점은 무엇입니까? – dtb

+0

@dtb :이 경우에는 기능적 차이가있을 것으로 생각하지 않습니다. 'Buffer.BlockCopy'는 조금 더 제한적입니다 - 저수준 방식으로 구현 된 것 같지만 자세한 내용은 알지 못합니다. –

14

이 작업을 수행 할 수 있습니다 : 당신이 Linq에를 사용할 수없는 경우

using System.Linq 

// ... 

var newArray = oldArray.Skip(numBytes).ToArray(); 
0

, 당신이 이런 식으로 할 수있는 :

byte[] myArray = // however you acquire the array 

byte[] newArray = new byte[myArray.Length - 16]; 

for (int i = 0; i < newArray.Length; i++) 
{ 
    newArray[i] = myArray[i + 16]; 
} 

// newArray is now myArray minus the first 16 bytes 

또한 사건을 처리해야합니다 어디 배열 16 바이트 미만입니다.

6
나는 또한 언급 할 것이다

- 당신이 결과를 사용 계획에 따라, 종종 다른 방법은 사용하는 것입니다 ArraySegment<T>을 사용하여 배열의 나머지 부분에 액세스하십시오. 이렇게하면 일부 사용 시나리오에서 더 효율적으로 배열을 복사 할 필요가 없습니다.

ArraySegment<byte> segment = new ArraySegment<byte>(originalArray, 16, originalArray.Length-16); 

// Use segment how you'd use your array... 
관련 문제