2009-01-31 6 views
1

의 장점은 무엇입니까/컨테이너를 반복 이러한 두 가지 방법의 단점은/하나 당신이 선호합니까 컨테이너 왜 반복합니다 질문 : 나는 ++ 또는 ++ 내가? 왜?가장 좋은 방법은

답변

5

반복자가 중요하지 않은 경우 (즉, 포인터가 아닌 경우) ++ i는 임시로 복사본을 포함하지 않으므로 확실히 빠릅니다. 임시로 복사되거나 최적화되지 않을 수 있습니다.

첫 번째 형식은 조금 빠르지 만 루프에서 내용을 지우거나 삽입하면 잘못 될 수 있습니다. 컨테이너를 통해 단순한 반복에 대한

나는 간결하고 명확하게하기 위해 대부분의 시간
#define foreach BOOST_FOREACH // in some header 

foreach(MyType &element, any_container) { 
    // deal with element 
} 

를 사용합니다.

#define foreach   BOOST_FOREACH 
// ... 
Container<Item> container; 
// ... 
foreach (Item item, container) { 
    // do some stuff with the item 
} 
+0

멋지 네요, 나는 BOOST_FOREACH에 대해 몰랐습니다. 나는 부스트에서 점점 더 유용한 것을 발견하고있다. 이것도 사용하기 시작합니다. :) – Frank

3

최적화가 해제되어 있지 않으면 둘 다 동일합니다. i ++ 또는 ++ i의 경우, 임시 값을 포함하지 않기 때문에 ++가 더 효율적입니다.

1

언제나 두 번째 호출을 실제로 수행합니다. 여러 번의 호출이 종료 될 때가끔 걱정할 수도 있습니다. 나는 이것이 최적화 될 것이라는 인상하에 있었지만, 확실히 알지 못했다.

그리고 나는 분명히. 더 빠르면 i ++보다 느려지지 않습니다.

1

모든 반복에서 end()이 호출되지 않기 때문에 첫 번째 매개 변수가 빠릅니다. 그리고 아니요, 옵티마이 저가 컨테이너의 크기가이 반복에서 변경되었는지 (따라서 끝이 이동했는지) 알지 못하기 때문에이를 쉽게 캐싱 할 수 없습니다. 이것은 앨리어싱 문제로 인해 const 컨테이너에도 적용됩니다.

i++은 i의 복사본을 반환 한 다음 증분합니다. ++i 씩 증가한 다음 증가 된 값을 반환합니다. 따라서 반환 값을 무시할 때는 ++i을 사용하십시오. 복사 작업이 적어 작업이 적기 때문입니다. 옵티 마이저는 인라인 된 i++ 호출을 수정할 가능성이 매우 높으므로 ++i만큼 빠르지 만 여기에는 의존하지 않습니다.

나? 내가 사용한다

for(int i = 0; i < m.size(); i++) { 
    // ... do something with m[i] 
} 

그것은 가장 짧고 분명하다. 왜 int이고 MyClass::size_type이 아닌 이유는 무엇입니까? 더 간단하기 때문에 지금까지 가장자리 사례에 대해 걱정할 필요가 없었습니다. 왜 i++일까요? 기본 유형의 경우 항상 ++i에 최적화되어 있기 때문에 동료에게 혼동을주지 않습니다. 보너스로 숫자 값으로 i도 사용할 수 있습니다. 반복기를 사용하면 별도의 카운터를 유지하거나 std::distance을 사용해야합니다.

obecalp는이 listmap처럼 표준 컨테이너의 절반 작동하지 않는 것을 지적한다. 사실 적절한 반복자를 사용해야합니다. 또한 일반 코드를 작성할 때는 항상 iterator을 사용해야합니다.

+0

연산자는 [], map/set, list 등의 연산자를 지원하며 다른 연산자는 연산자 []를 지원하지 않는 컨테이너라고 가정합니다. – obecalp

+0

아, 그래! 한 번지도를 반복하면서, 나는 :: iterator 맵을 사용했다. 그리고 지금까지리스트를 사용한 적은 없지만 iterator를 사용했습니다. –

+0

int가 아닌 size_t를 사용해야합니다. < and >에 대한 부호있는 유형과 부호없는 유형을 혼합하는 것은 실수로 무한 루프의 엣지 경우를 추가하는 좋은 방법입니다. – Tom

2

일반 stl 반복기의 경우 많은 차이가 없지만 컬렉션이 복잡하고 끝을 요구하는 것이 비용이 많이 들고 결국 단 한 번만 더 빠를 수도 있습니다.

마찬가지로 ++ 대 i ++, ++는 iterator가 복잡한 클래스 인 경우 (stl 반복자에서와 같이 포인터가 아니라) 더 많은 비용이 드는 작업이 될 수 있습니다. ++의 경우 iterator를 증가시키고 있습니다. iterator의 복사본을 이전 상태로 반환합니다. ++에 대해서는 iterator가 현재 상태이기 때문에 자체에 대한 참조를 반환 할 수 있습니다.

일반적으로 프로파일 러에서 문제가 있음을 식별 할 때 코드를 최적화하는 것이 가장 좋습니다. 코드를 가능한 한 쉽게 읽을 수 있도록하는 것이 좋습니다.

+0

"코드 전체에 작은 속도 저하가 발생하여 누적되어 성능에 상당한 영향을 미치지 만 프로파일 러에서는 감지 할 수 없습니다"라는 말이 있는지 궁금합니다. –

+0

단어는 "java"입니다. o) – Tom

0

Boost.Foreach는 좋은 방법을 소개합니다.

for(Item i : Container) 
{ 
    dosomething(i); 
} 
0

는 C++ 루프 상황이 반복 논리를 요구하지 않는 경우 가장 효율적이다 "컨테이너의 모든 요소에 대해"