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

Reply via email to