Instead of trying to guess, why don’t you take a look?
Compiling the following code:
#include <utility>
#include <iostream>
struct Window
{
std::pair<int, int> pos;
std::pair<int, int> getPosition() const
{
return pos;
}
};
int main()
{
Window window{{42, 314}};
for (int i = 0; i < 10000; ++i)
std::cout << (i + window.getPosition().first) << std::endl;
}
With Clang 6.0.0, with level 3 optimization:
main: # @main
push r15
push r14
push rbx
mov r15d, 42
.LBB0_1: # =>This Inner Loop Header: Depth=1
mov edi, offset std::cout
mov esi, r15d
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
mov r14, rax
; Continua...
Realize that the value 42
was passed to the register r15d
and, whenever the loop prints the value of the first member of the pair, it is passed as argument pro std::cout.operator<<(int)
through the recorder esi
, copying straight from r15d
.
Something similar is done by GCC 8.1, with the same flags:
main:
push r12
push rbp
mov ebp, 42
push rbx
jmp .L7
; Continua...
.L7:
mov esi, ebp
mov edi, OFFSET FLAT:std::cout
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
mov r12, rax
; Continua...
The value of the first member of the pair is stored in the register ebp
, which is passed as parameter to std::cout.operator<<(int)
for esi
also.
See the two results on Godbolt.
As Maniero said, there are several factors at play when it comes to the compiler optimizing your code, so one should avoid guessing what will happen to your code. Isolate the problem and Compile locally, to see what the result is. Then, compile the entire project and see what the result is by comparing it to the isolated code. Finally, and most importantly, run a Profiling (Profiling), or a benchmark, of the isolated and non-isolated code, then optimize it in code (if necessary!) and compare the results with new profiling (I’m not even considering the architecture where your program will be running, but it would be good too). Just like this, you will be sure that your manual optimizations have been successful.
In most cases, premature optimization (i.e. trying to guess the execution behavior of your program and optimize on top of it) is harmful and can make much worse the optimizations that the compiler can do.
Always optimize thinking of the data that your program will process and little in code construction, comparing profiles to prove the success of optimizations.
Fantastic! I’m discovering a lot that I never imagined. Thank you so much for the tips and support!
– Rogério Dec