Jest niewielki performance advantage w użyciu operatorów preinkrementuj kontra operatorów postinkrementacja. W tworzeniu pętle, które używają iteratory, należy zdecydować się na stosowanie wstępnych przyrostów:
for (list<string>::const_iterator it = tokens.begin();
it != tokens.end();
++it) { // Don't use it++
...
}
Powodem wychodzi na jaw, gdy myślisz o tym, jak obaj operatorzy będą typowo implemented.The preinkrementuj jest dość prosta. Jednak, aby do post-przyrostu do pracy, trzeba najpierw wykonać kopię obiektu, czy rzeczywisty przyrost na oryginalny obiekt, a następnie powrót do kopiowania:
class MyInteger {
private:
int m_nValue;
public:
MyInteger(int i) {
m_nValue = i;
}
// Pre-increment
const MyInteger &operator++() {
++m_nValue;
return *this;
}
// Post-increment
MyInteger operator++(int) {
MyInteger clone = *this; // Copy operation 1
++m_nValue;
return clone; // Copy operation 2
}
}
Jak widać, w słupek - Implementacja inkrementacji obejmuje dwie dodatkowe operacje kopiowania. Może to być dość kosztowne, jeśli przedmiot, o którym mowa, jest nieporęczny. Powiedziawszy to, niektóre kompilatory mogą być wystarczająco inteligentne, aby uciec z jednym procesem kopiowania, poprzez optymalizację. Chodzi o to, że post-inkrementacja zwykle wymaga więcej pracy niż wstępnego inkrementu, a zatem rozsądnie jest przyzwyczaić się do umieszczania "++" przed iteratorami, a nie później.
(1) Kredyt na połączoną stronę.
Zobacz [to] [1]. [1]: http://stackoverflow.com/questions/24853/c-what-is-the-difference-between-i-and-i – sergio
Jeśli kod w C++ przez dłuższy czas , '++ it' zapewni znaczny wzrost wydajności. Nie w twoim kodzie, ale w czasie spędzonym na wyjaśnianiu ludziom, dlaczego nie robiłeś '++ it' w pierwszej kolejności. Ponieważ to naprawdę nie ma znaczenia w najmniejszym stopniu, równie dobrze możesz zrobić to w sposób, który nie doprowadzi do kłótni. –
@Dennis: Nie ma znaczenia * dużo * i bardzo często nie da się zmierzyć, ale w ciasnych pętlach może to mieć znaczenie. –