Ouch. mea culpa. It would be a good idea for preservesAll and
preservesCFG to have the same interface (since I, at least, thought that
they did 
Yup, I'll look into changing that when I have spare time (ha ha).
>instead of a simple:
> virtual const string& name() const { return "B"; }
Do you think it's a good idea to return a reference to a temporary?
Oops, sorry about that, I forgot to drop the reference:
virtual string name() const { return "B"; }
Are you claiming that most compilers are so grossly inefficient that
checking on every call is more expensive than creating the object on
every call? If you're going to be passing around objects, they have to
be created somewhere. By declaring things static (and preferably const
as well), the compiler has the opportunity to optimize away the
constructor call.
The compiler always has the opportunity to optimize away the constructor
call. Remember that if the compiler is thread-capable, that you don't
just have a simple test to see if it's initialized, you have to at least
have a second chance lock or atomic operation, which is slow and bigger.
Regardless of locking, accessing global variables (Which statics
effectively are) is a good way to stop the optimizer dead in its tracks,
especially with GCC.
To emphasize my main point though, I wasn't trying to say that the above
would be faster, my point is that it _doesn't need to be_ fast.
Premature optimization, evil, and all that.
> 2. Don't optimize things that don't have to be optimized. In general
> these methods aren't called enough, or only during debugging, so it
> is better to be clear than it is to save a few cycles. As a general
> rule, optimize for clarity, not performance. Often performance comes
> for free with clarity.
What could be more clear than "static X x; return x;"?
return X();
Remember you also need the initializer expression.
> 3. If you REALLY want to be efficient, think about other short-cuts. In
> this case, a constant string is always returned. You could change
> the virtual method to always return a const char*, therefore avoiding
> a copy constructor call that may be unneccesary:
A good reference-counted string implementation should efficiently handle
returning a const& as in this case. Of course, this is example code
that I hacked out in about ten minutes just to illustrate the problem,
so I would say that the goal is to optimize for speed of coding: I wrote
it as it came to me.
I understand that this wasn't meant to be the most optimal or thought out
code, I was just trying to get across the fact that it's not a good
default habit to get into for returning constant strings. As it stands,
returning a const char* (if you can) would be MUCH faster than without.
Again in the presence of possible threads, reference counted strings are
MUCH slower than always copying in some cases. A reasonable example of
this discussion is here, but there are many others:
http://www.gotw.ca/publications/optimizations.htm
http://www.gotw.ca/gotw/045.htm
The real point I was trying to make is that clear code is often efficient,
and only when you find that efficiency is actually a problem for a piece
of code should you resort to optimizations like this. Compiler optimizers
can be made smarter for a fixed cost (giving benefits to a wide variety of
codes), but code maintenance has a cost that grows with the complexity of
code (and individual optimizations like this only gives a benefit to one
particular part of the code). Increasing complexity for no real payoff
has no benefit.
-Chris
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/