Re: Habitual optimization
Steven T. Hatton wrote:
I have long wondered about certain programming styles/strategies and how
they can impact performance.
I understand that the intent of the examples in _C++ GUI Programming with Qt
4_ is pedagogical and, therefore, they should stress clarity over optimal
efficiency. Nonetheless, the code shown on pg 130 gives me an opportunity
to ask a question about coding strategy in general.
Page 18 of _C++ Coding Standards_ by Sutter and Alexandrescu tells us "It is
not premature optimization to reduce spurious temporary copies of objects,
especially in inner loops, when doing so doesn't impact code
complexity."
I'm not sure I'd agree with that, but it probably depends on
what they mean by "doesn't impact code complexity". If I have
to think about it, it could be argued that it impacts code
complexity.
In the end, you need to use a little bit of common sense as
well. If the temporary copie is of an std::list with a couple
of hundred thousand entries, you're probably better off paying
attention to it up front (supposing it is in a tight loop, of
course). If you're worried about copying an iterator a couple
times more than necessary, you're wasting your time.
In general, write the code cleanly, and if it isn't fast enough,
use the profile, and optimize what needs optimization. Worrying
about speed before the program actually works is generally
counter-productive.
My question is whether any clock cycles might be saved by
moving some of the arithmetic out of the loops? For example, would anything
be gained by defining:
const int dTick((rect.width() - 1)/settings.numXTicks);
and then writing:
int x = rect.left() + i * dTick;?
Or even `int x(rect.left());' outside the loop, and `x+=dTick'; inside the
loop?
It might. The results might also end up running slower
(although it's not too likely). This is the sort of
optimization compilers are very good at, however, so I wouldn't
worry about it in general. More importantly, any modifications
to do it this way later are local, so acting on it before the
profiler says you have to is simply stupid.
What about calls to functions such as settings.spanX()? If these values are
unchanged during the loop, can anything be gained by assigning them to a
constant before entering the loop?
Maybe. It depends on the compiler. The only way to know is to
profile.
void Plotter::drawGrid(QPainter *painter)
{
QRect rect(Margin, Margin,
width() - 2 * Margin, height() - 2 * Margin);
if (!rect.isValid())
return;
PlotSettings settings = zoomStack[curZoom];
QPen quiteDark = palette().dark().color().light();
QPen light = palette().light().color();
for (int i = 0; i <= settings.numXTicks; ++i) {
int x = rect.left() + (i * (rect.width() - 1)
/ settings.numXTicks);
double label = settings.minX + (i * settings.spanX()
/ settings.numXTicks);
painter->setPen(quiteDark);
painter->drawLine(x, rect.top(), x, rect.bottom());
painter->setPen(light);
painter->drawLine(x, rect.bottom(), x, rect.bottom() + 5);
painter->drawText(x - 50, rect.bottom() + 5, 100, 15,
Qt::AlignHCenter | Qt::AlignTop,
QString::number(label));
}
//...
}
I'm confident that the first part of any answer to these questions will
be "It depends...". The term "optimizer" will probably arise as well. I
also realize my arithmetic modifications might change the behavior of the
code due to the evaluation order of the multiplicative operations.
In sum, you know the answer. So why ask the question?
One additional question I have deals with for-loops.
std::vector<Object> v;
// fill the vector
for(unsigned i(0); i<v.size(); ++i){
//do something.
}
Is it likely that an optimizer could improve performance if it could
determine that v.size() is unchanged during the loop, and thus eliminate
calls to v.size()?
Maybe. I'm sure that some compilers can do this. But not all.
On the other hand, if v.size() is inlined, "calling" it each
time through the loop, rather than keeping it in a register, is
one extra memory access. It would have to be a very simple loop
for this to make a difference. Again---write the most natural
form, then if the program is too slow, and the profiler says
that it is because of this loop, start experimenting.
--
James Kanze (Gabi Software) email: james.kanze@gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]