Hello Michael,
I've recently encountered this same problem myself. My experiments show
that iterating over a vector with an iterator is ***TEN TIMES SLOWER***
than with iterator debugging disabled. In release builds!
I'm somewhat skeptical of this claim. What experiments were they, and
are you sure they're representative of an actual application?
Sure, we all know that iterator debugging (_HAS_ITERATOR_DEBUGGING) and
checking (_SECURE_SCL) takes a lot of time in debug builds, but release
builds should be virtually unaffected. Note that _HAS_ITERATOR_DEBUGGING
only has an effect in debug builds - it is completely disabled in
release - but _SECURE_SCL stays enabled even in release. However, in my
testing, it has virtually no effect in release.
Think about it - would MS really put default values into their compiler
that would make all applications on their platform ten times slower? How
would that make their platform look, especially now that most
applications can run on multiple platforms?
I think you may be focusing on test cases that do not match actual
application results, but of course to be sure you'd have to publish your
test cases.
Ideally I'd just define _SCL_SECURE to 0, but I can't as I'm dependent
on closed-source libraries without it defined and this has given me
weird crashes.
We're on the same boat. We have to make two builds of everything because
in some builds we link to Vega Prime which is built with iterator
debugging disabled, but in all other cases we want to keep the VS
default values so we don't put an additional burden on our customers who
want to link to our libraries. It just about doubles the number of
builds we need in our build matrix, which is a drag.
I personally think that until we can publically and conclusively prove
otherwise, changing the VS default values for this is not useful and
just puts an additional burden on others trying to link to your libs.
See what happens with Vega Prime - because they decided to change the
iterator debugging setting, they force us to make twice the number of
builds. That's a considerable waste of time and resources for us.
A while ago, we tried building all our libraries with iterator debugging
and _SECURE_SCL turned off. We thought it would be a good way to reduce
our build matrix, but it ended up just moving the burden onto support
because customers who wanted to link to our libraries had to remember to
disable these in their projects too. Anyways - we switched back to
default settings on our OSG-based builds lately, and as I said I haven't
seen a significant performance difference in release. That's for actual
applications in a real-world setting... I didn't do any real timings at
the time, but I think I would have noticed a 10x difference! Especially
since OSG is iterator-heavy.
Remember - you're not supposed to do any benchmarking in debug (it's not
representative of real performance, on any platform) and release builds
*should* be relatively unaffected (unless you can prove otherwise).
However, I've discovered that using std::for_each in place of a for loop
provides a massive speed up - it performs the same is if iterator
debugging were disabled.
I'm skeptical about this too... Here's the source for std::for_each
(MSVC's implementation):
// TEMPLATE FUNCTION for_each
template<class _InIt,
class _Fn1> inline
_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
{ // perform function for each element
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Func);
_CHECKED_BASE_TYPE(_InIt) _ChkFirst(_CHECKED_BASE(_First));
_CHECKED_BASE_TYPE(_InIt) _ChkLast(_CHECKED_BASE(_Last));
for (; _ChkFirst != _ChkLast; ++_ChkFirst)
_Func(*_ChkFirst);
return (_Func);
}
Apart from the 2 _DEBUG and 2 _CHECKED macros, this does not do anything
different than I would do manually. It could be rewritten:
void for_each(iterator first, iterator last, function_ptr function)
{
for (; first!= last; ++first)
function(*first);
}
Now, out of the 4 macros, the first two are enabled if iterator
debugging is enabled (_HAS_ITERATOR_DEBUGGING), and the other two are
enabled if _SECURE_SCL is enabled. Now, the savings you see might come
from the fact that the iterators are checked only once and then
unchecked iterators are used for the loop itself. That would actually
make sense. But I haven't seen any significant performance difference
between the two myself, so I'm skeptical.
I agree with Robert, changing all loops to std::for_each wholesale would
be likely to introduce bugs, since you need to code up a functor for
each loop. In addition to introducing more code, that moves the inner
loop logic out of the scope where it's used, which makes it harder to
follow.
If we could use boost::foreach instead - and if we could prove that it
has the same benefits that you say std::for_each has - then that might
be a good alternative, because it allows a more classic loop structure
where the code stays local, no need for functors. But introducing boost
as a dependency for OSG is out of the question, as has been stated often
by Robert.
Anyways, I hope I didn't come out too strongly. I'd be glad if we could
find a way to get a massive speed-up, of course, but I'm skeptical about
the results you claim to get, that's all.
J-S
--
______________________________________________________
Jean-Sebastien Guay [email protected]
http://www.cm-labs.com/
http://whitestar02.webhop.org/
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org