Stroustrup의 “The C ++ Programming Language”를 읽고 있었는데, 여기서 그는 변수에 무언가를 추가하는 두 가지 방법 중
x = x + a;
과
x += a;
그는 더 +=
잘 구현 될 가능성이 높기 때문에 선호합니다 . 나는 그가 더 빨리 작동한다는 것을 의미한다고 생각합니다.
하지만 정말로 요? 컴파일러 및 기타 사항에 따라 다르면 어떻게 확인합니까?
답변
모든 컴파일러 가치는 소금 정확히 어떤 내장 유형 (모두 구조에 대한 동일한 시스템 언어 시퀀스를 생성 int
, float
긴 문장이 정말 단순하게만큼, 등) x = x + a;
및 최적화하는 것이 활성화된다 . (특히 -O0
기본 모드 인 GCC 는 디버거가 항상 변수 값을 찾을 수 있도록 완전히 불필요한 저장소를 메모리에 삽입하는 것과 같은 최적화 방지를 수행 합니다.)
그러나 진술이 더 복잡하다면 다를 수 있습니다. f
포인터를 반환하는 함수 라고 가정 하면
*f() += a;
f
한 번만 호출 하는 반면
*f() = *f() + a;
두 번 호출합니다. 경우 f
부작용이있다, 둘 중 하나는 (후자 아마) 잘못된 것입니다. 설사f
부작용이 컴파일러는 두 번째 호출을 제거하지 못할 수 있으므로 후자는 실제로 더 느릴 수 있습니다.
그리고 우리가 여기서 C ++에 대해 이야기하고 있기 때문에, operator+
과 operator+=
. 경우 x
최적화하기 전에 – – 다음 같은 유형이다 x += a
로 변환
x.operator+=(a);
반면에 x = x + a
번역
auto TEMP(x.operator+(a));
x.operator=(TEMP);
이제 클래스가 제대로 작성 되고 컴파일러의 옵티마이 저가 충분하면 둘 다 동일한 기계어를 생성하지만 내장 유형과 같은 확실한 것은 아닙니다. 이것은 아마도 Stroustrup이 +=
.
답변
동일하게 될 dissasembly를보고 확인할 수 있습니다.
기본 유형의 경우 둘 다 똑같이 빠릅니다.
이것은 디버그 빌드에 의해 생성 된 출력입니다 (예 : 최적화 없음).
a += x;
010813BC mov eax,dword ptr [a]
010813BF add eax,dword ptr [x]
010813C2 mov dword ptr [a],eax
a = a + x;
010813C5 mov eax,dword ptr [a]
010813C8 add eax,dword ptr [x]
010813CB mov dword ptr [a],eax
사용자 정의 유형 이 오버로드 할 수 있습니다, operator +
그리고 operator +=
, 그것은 각각의 구현에 따라 달라집니다.
답변
예! 후자의 경우 x
부작용 이 있을 수있는 경우 쓰기가 더 빠르고 읽기가 더 빠르며 알아내는 것이 더 빠릅니다 . 그래서 인간에게는 전반적으로 더 빠릅니다. 일반적으로 인간의 시간은 컴퓨터 시간보다 훨씬 더 비싸므로 여러분이 요청한 것이 틀림 없습니다. 권리?
답변
x와 a의 유형과 +의 구현에 따라 달라집니다. 에 대한
T x, a;
....
x = x + a;
컴파일러는 그것을 평가하는 동안 x + a의 값을 포함하기 위해 임시 T를 만들어야합니다. 그런 다음 x에 할당 할 수 있습니다. (이 작업 중에는 x 또는 a를 작업 공간으로 사용할 수 없습니다.)
x + = a의 경우 임시가 필요하지 않습니다.
사소한 유형의 경우 차이가 없습니다.
답변
의 차이 x = x + a
와는 x += a
기계가 통과하는 일의 양입니다 – 어떤 컴파일러는 (일반적으로 할) 수 멀리 최적화,하지만 우리는 잠시 동안 최적화를 무시하면 일반적으로, 무슨 일 것은 그 이전의 코드에서, 머신은 값을 x
두 번 조회해야하지만 후자의 경우이 조회는 한 번만 발생하면됩니다.
그러나 내가 언급했듯이 오늘날 대부분의 컴파일러는 명령을 분석하고 필요한 기계 명령을 줄일 수있을만큼 지능적입니다.
추신 : Stack Overflow에 대한 첫 번째 답변!
답변
이 C ++에 레이블을 지정 했으므로 게시 한 두 가지 진술에서 알 수있는 방법이 없습니다. ‘x’가 무엇인지 알아야합니다 (답변 ’42’와 약간 비슷합니다). x
POD 라면 실제로 큰 차이를 만들지 않을 것입니다. 그러나 x
클래스 인 경우 실행 시간이 매우 다른 다른 동작을 가질 수 있는 operator +
및 operator +=
메서드에 대한 오버로드가있을 수 있습니다 .
답변
+=
컴파일러의 삶을 훨씬 더 쉽게 만들고 있다고 말한다면 . 컴파일러 x = x+a
가 이것이와 동일한 것을 인식 x += a
하려면 컴파일러는
-
왼쪽 (
x
)을 분석하여 부작용이없고 항상 동일한 l- 값을 참조하는지 확인합니다. 예를 들어, 일 수 있으며z[i]
둘 다z
및i
변경되지 않도록해야합니다 . -
오른쪽 (
x+a
)을 분석하고 합계인지 확인하고에서와 같이 변환 할 수 있더라도 왼쪽이 오른쪽에서 한 번만 발생하는지 확인합니다z[i] = a + *(z+2*0+i)
.
당신이 의미하는 것이에 추가 a
하는 것이라면 x
컴파일러 작성자는 당신이 의미하는 바를 말할 때 그것을 고맙게 생각합니다. 그렇게하면 작성자 가 모든 버그를 제거 하기를 바라는 컴파일러의 일부 를 사용하지 않고 솔직히 머리를 뺄 수없는 경우 가 아니라면 실제로 삶을 더 쉽게 만들 수 없습니다. 포트란 모드의.