2011-07-26 5 views
0

방법 1과 방법 2의 장점/단점은 무엇입니까?루프에 대한 재사용 변수의 위치

방법 1 :

for (std::vector<MyObject*>::iterator it = my_objects.begin(); it != my_objects.end(); ++it) 
{ 
    Vector2 temp_position = (*it)->GetPosition(); 
    // do something... 
} 

방법 2 : temp_position 변수는 루프를 통해 각 시간을 다시 할 필요가 없습니다 때문에

Vector2 temp_position; // I do NOT need scope for this object outside of the loop. 
for (std::vector<MyObject*>::iterator it = my_objects.begin(); it != my_objects.end(); ++it) 
{ 
    temp_position = (*it)->GetPosition(); 
    // do something... 
} 

이론적, 방법 2 방법 1보다 더 나은 성능을 것입니다 . 그러나, 나는 컴파일러가 그것들을 동일하게 최적화 할 것을 읽었던 것을 기억한다.

temp_position에는 불필요한 범위가 없다는 점에서 방법 1이 더 좋습니다.

+2

조숙 한 최적화는 모든 악의 뿌리입니다. –

+0

가능한 한 읽을 수 있도록 코드를 작성하십시오. 당신의 임무는 알고리즘을 정확하게하는 것입니다. 컴파일러 작업은 최적화를 수행하는 것입니다. 당신이 당신의 일을하고 그것의 일을하게한다면 당신은 모두 행복 할 것입니다. –

답변

2

컴파일러가 수행하는 최적화를 무시하면 각 버전에서 호출하는 함수 사이에 구체적인 차이가 있습니다.

방법 1에서는 루프 내에 벡터를 생성하므로 해당 생성자가 한 번 (특히 복사 생성자) 호출되고 해당 루프의 반복마다 소멸자가 한 번 호출됩니다. 그래서 대충 비용은 N 복사 생성자 호출 + N 소멸자 호출입니다.

방법 2에서 벡터가 이미 for 루프에 있으므로 복사 할당 연산자가 대신 호출됩니다. 그래서 생성자는 한번 호출되고, 소멸자는 한번 호출되고, 복사 할당 연산자는 N 번 호출됩니다. 대략적인 비용은 1 복사 생성자 호출 + 1 소멸자 호출 + N 복사 할당 연산자 호출입니다.

그들은 얼마나 많은 작업이 이루어 졌는지 거의 비슷합니다. 카피 할당 연산자를 호출 할 때마다 하나의 배열을 할당하고 다른 배열을 해제해야합니다. 반면에 복사 생성자 호출은 하나의 배열을 할당하는 반면 소멸자는 하나의 배열을 할당합니다.

나는 방법 1을 선호하는 이유는 단순히 말하고있는 것을 더 가깝게 반영하기 때문입니다. 벡터는 실제로 임시적이며 루프의 범위를 벗어나있을 필요가 없습니다.

1

"조기 최적화는 모든 악의 뿌리입니다." - Etienne de Martel

아멘. 그러나 나는 잠깐 동안 나의 후광을 놓치고 컴파일러가 아마 그 루프를 최적화 할 것이고 어쩌면 스택에 대한 할당 비용 대 다른 모든 복사 및 할당 비용을 완전히 풀 수 있다고해도 무의미하다.

나는 컴파일러가 아마 그것과 함께 할 것이고 그것이 그날의 끝에서 기쁘게하는 것을 할지라도 아래처럼 그 루프를 쓸 것이다.

const std::vector<MyObject*>::const_iterator end(my_objects.cend()); 
for (std::vector<MyObject*>::const_iterator it(my_objects.cbegin()); it != end; ++it) 
{ 
    Vector2 temp_position((*it)->GetPosition()); 
    // do something... 
} 
+0

+1 - 더 나은 점은 for 루프 안에 end 변수를 두는 것입니다. – antsyawn

+0

@antsyawn 따라서 조숙 한 최적화가 왜 모든 악의 뿌리 인 이유는? 컴파일러가 거의 무시할 수있는 작은 조정의 양은 끝이 없습니다. 그것은 오늘의 끝이고 나는 커피를 마셨다. 그래서 우리는 어셈블리와 나머지를 이것에서 벗어날 것이다. – AJG85

+0

성능 문제를 무시하고, 범위 지정을하기 위해 for 루프 안에 end var를 넣는 것을 선호한다. 중요 - 코드를 깨끗하고 유지 보수 할 수 있도록 유지합니다. for (Container :: iterator i = container.begin(), end = container.end(); i! = end; ++ i) – antsyawn

관련 문제