Напишите все, что логически логично (обычно ближе к использованию).Компилятор может и будет определять такие вещи и генерировать код, наиболее подходящий для вашей целевой архитектуры.
Ваше время далеко более ценно, чем пытаться угадать взаимодействия компилятора и кэша на процессоре.
Например, для x86 эта программа:
#include <iostream>
int main() {
for (int j = 0; j < 1000; ++j) {
std::cout << j << std::endl;
}
int i = 999;
std::cout << i << std::endl;
}
по сравнению с:
#include <iostream>
int main() {
int i = 999;
for (int j = 0; j < 1000; ++j) {
std::cout << j << std::endl;
}
std::cout << i << std::endl;
}
скомпилировано с:
g++ -Wall -Wextra -O4 -S measure.c
g++ -Wall -Wextra -O4 -S measure2.c
Когдапроверка вывода с помощью diff measure*.s
дает:
< .file "measure2.cc"
---
> .file "measure.cc"
Даже для:
#include <iostream>
namespace {
struct foo {
foo() { }
~foo() { }
};
}
std::ostream& operator<<(std::ostream& out, const foo&) {
return out << "foo";
}
int main() {
for (int j = 0; j < 1000; ++j) {
std::cout << j << std::endl;
}
foo i;
std::cout << i << std::endl;
}
vs
#include <iostream>
namespace {
struct foo {
foo() { }
~foo() { }
};
}
std::ostream& operator<<(std::ostream& out, const foo&) {
return out << "foo";
}
int main() {
foo i;
for (int j = 0; j < 1000; ++j) {
std::cout << j << std::endl;
}
std::cout << i << std::endl;
}
результаты diff сборки, произведеннойg++ -S
все еще идентичны, за исключением имени файла, потому что нет никаких побочных эффектов.Если бы были побочные эффекты, то это указывало бы, где вы сконструировали объект - в какой момент вы хотели, чтобы побочные эффекты происходили?