2013-07-07 2 views
-1

벡터에 벡터 수준이 너무 높다는 것에 대해 걱정해야합니까? 예를 들어, 나는 5 단계의 계층 구조를하고 난 내 모든 프로젝트를 통해 코드 의이 종류가 있습니다벡터에서 벡터의 레벨이 너무 많다는 것에 대해 걱정해야합니까?

각 요소는 벡터이다
rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d] 

.

Block b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d]; 
// use b 

두 번째 방법은 훨씬 좋네요,하지만 느린 것 같아요 : 모든 것은 훨씬 빨리 다음과 같이 객체를 복사하는 것보다해야 여전히 사용 벡터의 벡터의 벡터 ... 입니다. 내가 대신

+3

성능에 대해서는 걱정할 필요가 있지만 걱정하지 않아야합니다. – delnan

+0

구조체가 희소 할 경우 특히 pos와 위치 사이에보다 일반적인 매핑을 고려하는 것이 좋습니다. 예를 들어, 'unordered_map'이 여기서 유용 할 수 있습니다. –

+0

@delnan 당신이 뭔가를 말할 때 그 이유를 말해야한다고 생각합니다. – user2381422

답변

2

효율은 코드에서 실제로 영향을받지 않습니다 (벡터 임의 액세스의 비용은 기본적으로 아무것도 아닙니다). 염려해야 할 것은 벡터 데이터 구조의 남용입니다.

복잡 할 정도로 클래스에 벡터를 사용해야하는 이유는 거의 없습니다. 제대로 정의 된 인터페이스를 가진 클래스가 코드를 더 효율적으로 만들지는 않지만 앞으로는 유지 관리를 훨씬 쉽게 할 것입니다.

현재 솔루션도 정의되지 않은 동작을 실행할 수 있습니다.예를 들어 사용자가 게시 된 코드를 가지고 :

Block b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d]; 

를 벡터 인덱스가 pos.a에 의해 참조하면, pos.b는, pos.cpos.d 그 벡터 중 하나에 무엇을 존재하지 않는 일이 발생 지금은? 정의되지 않은 동작으로 들어가고 응용 프로그램이 아마도 segfault (운이 좋다면) 할 것입니다.

수정하려면 Block 개체를 검색하기 전에 ALL 벡터의 크기를 비교해야합니다.

Block b; 
if ((pos.a < rawSheets.size()) && 
    (pos.b < rawSheets[pos.a].countries.size()) && 
    (pos.c < rawSheets[pos.a].countries[pos.b].cities.size()) && 
    (pos.d < rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks.size())) 
{ 
    b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d]; 
} 

블록을 만들 때마다 실제로 그렇게 할 예정입니까?

class RawSheet 
{ 
    Block & FindBlock(const Pos &pos); 

    std::vector<Country> m_countries; 
}; 

Block & RawSheet::FindBlock(const Pos &pos) 
{ 
    if ((pos.b < m_countries.size()) && 
     (pos.c < m_countries[pos.b].cities.size()) && 
     (pos.d < m_countries[pos.b].cities[pos.c].blocks.size())) 
    { 
     return m_countries[pos.b].cities[pos.c].blocks[pos.d]; 
    } 
    else 
    { 
     throw <some exception type here>; 
    } 
} 

그런 다음이처럼 사용할 수 있습니다

당신

예 ... 것을 할 수있는, 또는 당신은, 적어도, 수업 시간에 그것을 마무리 할 수 ​​있습니다 :

최소한
try 
{ 
    Block &b = rawSheets[pos.a].FindBlock(pos); 

    // Do stuff with b. 
} 
catch (const <some exception type here>& ex) 
{ 
    std::cout << "Unable to find block in sheet " << pos.a << std::endl; 
} 

, 당신은 RawSheet 클래스 내부에서 벡터를 계속 사용할 수 있지만,이 방법은 내부에있는, 당신은 일을 제거 할 수 있습니다 e 벡터 악용을 나중에 다른 곳에서 코드를 변경할 필요가 없습니다 (참조 : Law Of Demeter)!

+0

감사합니다! 어쩌면 FindBlock 함수를 const로 만들어야합니까? – user2381422

+0

Re : 범위 밖의 'pos. *'values ​​: 이것에 대해 걱정할 경우'std :: vector :: at()'를 사용하십시오 (많은 사람들은 그렇지 않습니다. 또한, demeter의 법칙도'FindBlock' 구현에 적용될 것입니다. – delnan

+0

인덱스를 확인하는 것은 문제가되지 않습니다. 우리는 이러한 것들을 빠르게 유지하기 위해 항상 유효한 인덱스를 제공하는 전략을 가지고 있으므로 체크가 필요 없습니다. 그러나 나는 그 기능을 좋아하고 지금 그것을 구현할 것이다. – user2381422

1

사용 참조를 ...이 관련된 성능 문제, 또는 다른 사람에 대해 걱정

감사해야하는 경우

나에게 어떤 제안을주십시오. 이것은 객체를 복사하지 않고 더 쉽게 사용할 수 있도록 별칭을 만들므로 성능에 영향을 미치지 않습니다.

Block& b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d]; 

(앰퍼샌드보기). b를 사용하면 원래 벡터로 작업하게됩니다.

그러나 @delnan 메모에서 코드 구조에 대해 더 걱정해야합니다. 더 적절하고 메인터넌스 할 수있는 방법으로 다시 작성해야합니다.

+0

좀 더 구체적으로 알려주시겠습니까?그것을 다시 작성하는 방법을 모르겠다. 나는 정말 그런 계층 구조의 여러 수준에 액세스 할 수 있어야한다. 그건 그렇고 참고 조언, 아주 좋은 주셔서 감사합니다! – user2381422

+1

지금 당장 어떻게 작동 하는지를 알기 전까지는 구조 조정의 의미에서 여러분을 도울 수 없습니다. 그러나 당신이 이미 이런 방식으로 해왔다면 그렇게하기가 쉽지 않을 것이라고 생각합니다. 단지 참조를 사용하여 더 유용하게 만들 수 있습니다. –

+0

또는 약간의 변경을 원한다면 @KarlNicoll 응답을보십시오. –

-1

귀하의 프로그램에 대한 제약 사항이나 프로그램이 무엇을하는지 모르기 때문에 특정 답변에 대해 걱정해야합니까?

주어진 코드는 우리가 알지 못하면별로 나쁘지 않습니다.

표시된 첫 번째 접근법과 두 번째 접근법은 기능적으로 동일합니다. 둘 다 기본적으로 객체 참조를 반환하지만 할당에 따라 복사본이 만들어 질 수 있습니다. 두 번째 확실합니다.

사샤 (Sasha)는 개체 복사본이 아니라 참조를 원한다는 점에서 좋습니다. 사용 방법에 따라 const로 만들 수 있습니다.

벡터로 작업하기 때문에 각 통화는 고정 된 시간이므로 매우 빠릅니다. 정말로 염려한다면 시간을두고 초당 호출 빈도를 고려하십시오.

또한 데이터 세트의 크기를 고려해야하며 다른 데이터 구조 (데이터베이스)가 더 적합한 지 생각해야합니다.

관련 문제