2011-02-09 7 views
2

포인트는 여기에서 opimization입니다. 이제Delphi TBytes - 복사하는 방법?

:

내가 무엇을 달성하고자하는
type TSomeClass=class(TObject) 
    private 
    DataWrite: TBytes; 
    ... 
end; 

Function TSomeClass.GetPacket: TBytes; 
begin 
    SetLength(Result, Length(DataWrite)); 
    Move(DataWrite[0],Result[0],Length(DataWrite)); 
end; 

: 훨씬 빠른 있도록

델파이 배열의 첫 번째 요소에 대한 포인터이기 때문에
Function TSomeClass.GetPacket: TBytes; 
begin 
    Result := DataWrite; 
end; 

이, 후자의 경우에만 만 4 바이트를 기록합니다. 이 올바른지?

+2

당신이 참조 데이터를 복사하거나 복사 하시겠습니까? –

답변

2

그래도 작업 할 수 있지만 이제는 GetPacket을 호출하는 클라이언트 코드에서 동일한 바이트 배열로 작업하고 있음을 알 수 있습니다. 이것은 나쁜 생각 일 수 있습니다. 바이트 배열에 대해 몇 가지 추가 압축 또는 암호화를 수행하는 네트워크 라이브러리를 고려하십시오. 이것은 노출 된 인터페이스를 사용하지 않고도 클래스와 상호 작용할 수있는 많은 가능성을 창출합니다. 따라서 IMHO 복사가 더 나은 옵션입니다.

현재 : 여기서 말하는 배열의 크기는 어느 정도입니까?

+0

감사합니다. 내가 필요한 확인 만. ;) – JBA

+0

이 클래스는 일반적인 쓰기/읽기 용 클래스입니다. 그리고 그것을 보내려면 GetPacket을 사용하고 싶습니다. 암호화는 리더/라이터의 바이트 배열에서 수행 될 것입니다. – JBA

7

동적 배열은 "쓰기 복사"가 아니라 문자열과 다른 점을 알아야합니다.

문자열 또는 동적 배열을 할당하면 힙의 데이터에 대한 포인터 만 복사되고 참조 횟수가 증가합니다.

그러나 참조 번호가 1보다 큰 문자열 (예 : s [1] : = 'a')에 문자열을 쓰면 컴파일러에서 문자열이 먼저 복사되는 코드를 생성합니다 . 당신이 GetPacket가 호출 된 후 DataWrite의 내용을 변경하는 경우

var 
    s, t: string; 
    a, b: TBytes; 
begin 
    s := 'abc'; 
    t := s; 
    t[2] := 'X'; 
    WriteLn(s); //still abc 

    a := TBytes.Create(1, 2, 3); 
    b := a; 
    b[1] := 0; 
    WriteLn(a[1]); // is now 0 not 2! 

그래서 코드의 경우, 변화가 GetPacket 반환 된 테라 바이트에 표시됩니다 : 이것은 동적 배열의 경우되지 않습니다. 대신 SetLength를 그리고 이동 전화의 당신이 실제로 배열의 복사본을 만드는 코드를

, 당신은 사용할 수 있습니다

function TSomeClass.GetPacket: TBytes; 
begin 
    Result := Copy(DataWrite, 0, High(Integer)); 
end; 
+0

+1은 문자열과 동적 배열 사이의 copy-on-write 의미의 차이를 지적합니다. – jpfollenius

+0

또는 간단하지만 아직 쓸 수 있습니다 결과 : = Copy (DataWrite); – Larsdk

+0

@Larsdk, 고마워, 그걸 몰랐어. 절대로 시도하지 않았으며 Code Insight는 마지막 두 매개 변수를 선택적으로 표시하지 않습니다. –

관련 문제