x + =가 x = x + a보다 빠릅니까?
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의 경우 임시가 필요하지 않습니다.
사소한 유형의 경우 차이가 없습니다.
The difference between x = x + a
and x += a
is the amount of work the machine has to go through - some compilers may (and usually do) optimize it away, but usually, if we ignore optimization for a while, what happens is that in the former code snippet, the machine has to lookup the value for x
twice, while in the latter one, this lookup needs to occur only once.
However, as I mentioned, today most compilers are intelligent enough to analyse the instruction and reduce the resulting machine instructions required.
PS: First answer on Stack Overflow!
As you've labelled this C++, there is no way to know from the two statements you've posted. You need to know what 'x' is (it's a bit like the answer '42'). If x
is a POD, then it's not really going to make much difference. However, if x
is a class, there may be overloads for the operator +
and operator +=
methods which could have different behaviours that lead to very different execution times.
If you say +=
you're making life a lot easier for the compiler. In order for the compiler to recognize that x = x+a
is the same as x += a
, the compiler has to
analyze the left hand side (
x
) to make sure it has no side effects and always refers to the same l-value. For example, it could bez[i]
, and it has to make sure that bothz
andi
don't change.analyze the right hand side (
x+a
) and make sure it is a summation, and that the left hand side occurs once and only once on the right hand side, even though it could be transformed, as inz[i] = a + *(z+2*0+i)
.
If what you mean is to add a
to x
, the compiler writer appreciates it when you just say what you mean. That way, you're not exercising the part of the compiler that its writer hopes he/she got all the bugs out of, and that doesn't actually make life any easier for you, unless you honestly can't get your head out of Fortran mode.
You're asking the wrong question.
This is unlikely to drive the performance of an app or feature. Even if it were, the way to find out is to profile the code and know how it affects you for certain. Instead of worrying at this level about which is faster, it's far more important to think in terms of clarity, correctness, and readability.
This is especially true when you consider that, even if this is a significant performance factor, compilers evolve over a time. Someone may figure out a new optimization and the right answer today can become wrong tomorrow. It's a classic case of premature optimization.
This isn't to say that performance doesn't matter at all... Just that it's the wrong approach to achieve your perf goals. The right approach is to use profiling tools to learn where your code is actually spending its time, and thus where to focus your efforts.
For a concrete example, imagine a simple complex number type:
struct complex {
double x, y;
complex(double _x, double _y) : x(_x), y(_y) { }
complex& operator +=(const complex& b) {
x += b.x;
y += b.y;
return *this;
}
complex operator +(const complex& b) {
complex result(x+b.x, y+b.y);
return result;
}
/* trivial assignment operator */
}
For the a = a + b case, it has to make an extra temporary variable and then copy it.
기계와 아키텍처에 따라 달라져야한다고 생각합니다. 아키텍처가 간접 메모리 주소 지정을 허용하는 경우 컴파일러 작성자는 최적화를 위해이 코드를 대신 사용할 수 있습니다.
mov $[y],$ACC
iadd $ACC, $[i] ; i += y. WHICH MIGHT ALSO STORE IT INTO "i"
반면 i = i + y
에 (최적화없이) 번역 될 수 있습니다.
mov $[i],$ACC
mov $[y],$B
iadd $ACC,$B
mov $B,[i]
즉, if
i
is a function returning pointer 등과 같은 다른 합병증
도 고려해야합니다. GCC를 포함한 대부분의 프로덕션 수준 컴파일러는 두 문에 대해 동일한 코드를 생성합니다 (정수인 경우).
아니요, 두 가지 방법 모두 동일하게 처리됩니다.
참고 URL : https://stackoverflow.com/questions/12479486/is-xa-quicker-than-xxa
'developer tip' 카테고리의 다른 글
Java에서 이진 형식으로 정수 상수를 정의 할 수 있습니까? (0) | 2020.09.17 |
---|---|
Laravel Eloquent ORM 거래 (0) | 2020.09.17 |
MVC3 Razor DropDownListFor 열거 형 (0) | 2020.09.17 |
Android : 클릭시 임의의 색상 생성? (0) | 2020.09.17 |
C ++에서 숫자가 2의 거듭 제곱인지 테스트하는 가장 간단한 방법은 무엇입니까? (0) | 2020.09.17 |