2012-11-19 2 views
4

나는 할당 된 메모리와 많은 원시 타입 멤버들에 대한 포인터를 가지고있는 클래스를 가지고있다. 나는 이동 생성자에 대해 머리를 써서 이것이 하나를 사용할 수있는 완벽한 기회라고 생각한다. 분명히 포인터를 통해 이동해야하지만 idk 좋은 생각이있는 경우에는 idk.move constructor overkill

class Foo { 
private: 
    long m_bar = 1; 
    /* 20+ similar members */ 
}; 

는, 그들이 이동하게하려면 그들이 동적으로 할당되어야 할 것이다 :

다음은 클래스의 인위적인 예입니다.

class Foo { 
public: 
    Foo(Foo && rhs) : m_bar(rhs.m_bar) { rhs.m_bar = nullptr; } 
    ~Foo() { delete m_bar; } 
private: 
    long *m_bar = new long{1}; 
}; 

내 질문은 힙에 할당의 오버 헤드가 이동 의미에 의해 도입 된 성능 향상을 무효화 것입니까?

+2

"프리미티브"는 움직일 수 있습니다. –

+0

미안하지만 미안하지만 미안합니다. –

+0

정교하게 다루는 것이 많지 않습니다. 기본 유형의 객체를 이동하는 데는 아무 것도 할 필요가 없습니다. 그냥 작동합니다. –

답변

6

나는 이런 식으로 각 구성원을 할당하는 힙이 느려지 게 될 것이라고 믿습니다. 힙에있는 많은 작고 연속되지 않은 데이터 멤버에 대한 포인터를 유지하는 것은 초기에 힙 할당을 수행 할 때만 수행되며 CPU 캐싱 전략과 잘 일치하지 않습니다.

일부 클래스는 힙 할당 비트가 큽니다 (예 : std :: string). 귀하의 경우, 각 포인터를 움직이는 것은 귀하의 작은 데이터 유형을 이동하는 것만큼이나 비쌉니다. 이 빠른 방법을 볼 수있는 유일한 방법은 할당 된 힙 (아마도 unique_pointer 보유하는 클래스/구조체) 작은 데이터 멤버를 래핑하는 경우 및 단일 포인터의 이동을 통해 모두 이동하는 경우입니다.

그렇다고 조기 최적화의 경우 일 가능성이 높습니다. 코드가 어떻게 작동하는지 파악하고 클래스에 대한보다 복잡한 이동 의미를 구현하면 코드 성능에 실제로 도움이 될 수 있다고 판단 할 수 있습니다.

+3

조기 최적화를 위해 +1. 또한 OP가이 클래스를 사용하는 방법에 따라 다릅니다. 이동 된 것보다 더 자주 생성되는 경우에는 이동시 데이터 구조를 할당하는 것보다 이동 비용을 들일만한 가치가 있습니다. –

1

프리미티브가 포인터보다 더 크지 않고 (어떤 식 으로든) 복사하는 것보다 비싸지 않다면, 동적으로 할당하는 것은 추가 비용입니다.

원본을 무효로 할 수 있지만 포인터는 필요하지 않을 수 있습니다.

2

이동 시맨틱은 복사하는 것보다 오브젝트 이동이 빠를 때만 빠릅니다. 귀하의 예에서는 사실이 아닙니다. long을 복사하는 것은 동일한 속도로 포인터를 long으로 복사해야합니다. 각 개별 구성원을 동적으로 할당하여 이동 의미를 추가하면 속도를 높이는 것이 아니라 속도를 늦추는 것이 거의 확실합니다.

더 빠른 이동 생성자가 PIMPL 관용구를 사용하는 결과를 가져올 수 있습니다. 모든 구성원을 포함하는 하나의 클래스를 동적으로 할당하면 기본 클래스는 해당 클래스에 대한 포인터 만 포함합니다. 그런 다음 모든 이동 생성자는 포인터를 구현 클래스에 복사해야합니다.