copy_from_slice () 대신 clone_from_slice ()를 사용하면 성능이 저하됩니까?

Aug 15 2020

녹에, 거기에 다른 슬라이스에서 슬라이스의 내용을 업데이트하는 두 가지 방법은 다음과 같습니다 clone_from_slice()및 copy_from_slice(). 이 두 함수의 동작은 놀랍지 않습니다. 첫 번째는 복제를 수행하고 유형이 구현 될 것으로 예상하는 Clone반면 두 번째 함수는 복사를 수행하고 유형이 구현 될 것으로 예상합니다 Copy.

그러나에 대한 문서에 다음과 clone_from_slice같이 나와 있다는 사실이 놀랍습니다 . " T구현하는 경우 Copy를 사용하는 것이 더 성능이 좋을 수 있습니다 copy_from_slice." 여기에 성능 차이가 있어야한다는 것은 놀랍습니다. 경우 T를 구현 Copy한 후 .clone()비트를 복사와 동등 할 필요가있다; 그러나 컴파일러는 유형 T이 무엇인지 알고 있으므로 .NET을 사용하더라도 비트 복사를 수행 할 수 있는지 알아낼 수 있어야합니다 clone_from_slice.

그렇다면 성능 비효율은 어디에서 발생합니까?

답변

4 ÖmerErden Aug 15 2020 at 21:14

TL; DR clone_from_slice 의 소스를 확인하십시오. 슬라이스의 모든 요소를 ​​방문하고 clone각각을 호출 하고 있으며 copy_from_slice 는 memcpy.


T를 구현하는 경우 Copy, 다음 .clone()복사 비트에 해당 될 필요

모든 Copy유형이 Clone기본적으로 구현 되는 경우에도 clone직접copy ; clone_from_slice여전히 슬라이스를 횡단하고 횡단하는 동안 복사를 수행합니다.

그러나이 제안은 기본 요소에는 맞지 않지만 아래와 같은 경우에는 맞지 않습니다 .

#[derive(Copy)]
struct X;

impl Clone for X {
    fn clone(&self) -> Self {
        //do some heavy operation or light(depends on the logic)

        X
    }
}

Clone어떤 논리 Copy유형 으로도 구현할 수 있지만 객체를 복제 할 때 비트를 복사하기 만하면됩니다.

T가를 구현 Copy하면 사용하는 것이 더 효과적 일 수 있습니다.copy_from_slice

중요한 것은 여기에, 문서가 "라는 이 될 수있다 "없다 " 가 될 것 "이 같은 가능성을 제공합니다

  • Clone구현은 구현을 직접 사용할 수 있습니다 Copy. 프리미티브와 같은 기본 유형의 경우 옵티마이 저는 memcpy순회 대신 직접 사용할 수 있습니다 . 그러면 하나가 성능을 발휘하지 못하기 때문에이 제안을 잘못된 것으로 받아 들일 수 있습니다.

  • Clone구현은 구현을 직접 사용할 수 있습니다 Copy. 복잡한 유형 (위의 순회 문제)의 경우이 제안이 정확합니다. ( @kmdreko 의 예제 를 좀 더 복잡한 구조로 편집했습니다. godbolt 의 결과를 확인하십시오 )

  • Clone구현은 사용자 정의이고 Copy유형입니다. 이것은 사용자 정의 구현이 저렴하더라도이 제안을 올바르게 만들 것 copy입니다. 그러면 큰 슬라이스를 사용하는 memcpy것이 더 유용 할 수 있습니다.