Why is VC8 code much slower than VC7.1?

I have built the code below using both MSVC 7.1 and 8.0 beta 2, using the command shown in the initial comment. When run on a 3GHz P4 with 1GB RAM, running XP SP2, the output is as follows:

   VC7.1: Time = 62
   VC8.0: Time = 110

Why does the 8.0 build take 1.77 times as long to run

Thanks,
Keith MacDonald

/////////////////////////////////
// cl -Ox -EHsc -MT TimeTest.cpp

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
#include <vector>
#include <algorithm>

class View;

class Document
{
public:
    Document()
    {}

    void Subscribe(View* pView)
    {
        m_subscribers.push_back(pView);
    }

    void Unsubscribe(View* pView)
    {
        list_t::iterator it = std::find(m_subscribers.begin(), m_subscribers.end(), pView);

        if (it != m_subscribers.end())
            m_subscribers.erase(it);
    }

    void Notify() const;

private:
    typedef std::vector<View*>  list_t;
    list_t                      m_subscribers;
};

class View
{
public:
    View(Document& m)
        : m_document(m)
    {
        m_document.Subscribe(this);
    }

    virtual ~View()
    {
        m_document.Unsubscribe(this);
    }

    virtual void Update() = 0;

protected:
    Document&   m_document;
};

class TextView : public View
{
public:
    TextView(Document& m)
        : View(m)
    { }

    virtual void Update()
    { }
};

class HexView : public View
{
public:
    HexView(Document& m)
        : View(m)
    { }

    virtual void Update()
    { }
};

void Document::Notify() const
{
    for (list_t::const_iterator it = m_subscribers.begin(); it != m_subscribers.end(); ++it)
        (*it)->Update();
}

int main()
{
    Document    doc;
    TextView    v1(doc);
    HexView     v2(doc);
    const DWORD dwTime = ::GetTickCount();

    for (int i = 0; i < 6000000; ++i)
        doc.Notify();

    std::cout << "Time = " << ::GetTickCount() - dwTime << std::endl;
    return 0;
}

 




Answer this question

Why is VC8 code much slower than VC7.1?

  • Carole Akoury

    Martyn,

    I've just run the same test with VC8 RC1 that I did with beta 2 last May, and it still runs at half the speed of a VC 7.1 build.  Is this as good as it's going to get

    Thanks,
    Keith MacDonald

  • mralx

    Keith,

    In VC8.0 STL does lot of checks to minimize chances that you'll get buffer overruns, memory overwrites, etc. That is new feature that was requested by lot of customers, and it goes on nicely with other security enhancements we made in the product.

    New STL is much safer than the old one; we (and our customers) found lot of problems in the programs that incorrectly used STL.

    Those changes cause some overhead, and they can cause slowdown, especially in the small synthetic benchmarks, where all the time is spent in STL code itself. There are ways that allows compiler to remove some NULL and bounds checks (both libraries and compiler changes may be necessary), but unfortunately we didn't have enough time to fully address those issues. We will work on improving secure STL performance in the next VC version.

    If you think you need the latest bit of performance, and you are ready to sacrify some security to achieve that performance, you can specify compiler flag

        /D_SECURE_SCL=0

    when compiling your application. That will turn security/safety chacks in STL headers, and its behavior will revert to pre-VC8.0 compiler.

    Thanks,
    Eugene

  • mAcD

    Martyn,

    Thanks for your prompt response.

    It's good to hear that you are working on these performance issues, but it looks like there's a lot of work to do.  Most of the processor time in my sample is consumed by Document::Notify(), so based on your comments about the STD Library, I tried changing it to this:

    void Document::Notify() const
    {
        for (size_t n = 0; n != m_subscribers.size(); ++n)
            m_subscribers[ n ]->Update();
    }

    That increased the runtime from 110 to 141, so I then extracted the invariant part of the loop thus:

    void Document::Notify() const
    {
        const size_t    ncElems = m_subscribers.size();

        for (size_t n = 0; n != ncElems; ++n)
            m_subscribers[ n ]->Update();
    }

    This got the time back to 110.  As I'm compiling with /Ox, I'm very surprised that the optimiser doesn't handle that simple case already.  (The optimiser has definitely not been disabled for the public beta, as with no optimisations, the time increases to 265.)

    Maybe "Visual Studio 8" would be a safer name than "Visual Studio 2005", now that May is here. Wink

    Keith MacDonald



  • EddieBerman

    Hey,

    I have a similar problem of performance. My code (which is a genetic algorithm) is 3 times slower when compiled under Visual Studio 2005.

    With Visual Studio 2003, it used to run in 3.0639 seconds, and now it runs in 9.0031 seconds. I tried every optimization option, and adding the /D_SECURE_SCL=0 compiler command to the project options with only minor differences.

    Is there any other way to get back to the speed Visual Studio 2003 was giving It is a bit absurd to upgrade to a new compiler and get lesser performances in the compiled program.

    Thanks a lot!!!

    Antoine Atallah

  • Noddy

    void Document::Notify() const
    {
        for (size_t n = 0; n != m_subscribers.size(); ++n)
            m_subscribers[ n ]->Update();
    }

    You are calling virtual function in the loop. Optimizer doesn't know if that call modifies m_subscribers, so it cannot hoist m_subscribers.size() out of the loop.


  • braden2

    Hi Antoine,
      I am actually interested in investigating such slow performance. Could you please post a sample exhibiting the problem I will be more than happy to look at what is exactly happening.

    Thanks,
      Ayman Shoukry
      VC++ Team

  • pkoanui

    Keith,

    Thanks for the feedback. In the case of the standard C++ library, some of the checks we added were over-zealous in repeatedly re-verifying safety of algorithms. So for some cases you can see a large slowdown in beta 2 (larger than this, even.).

    However, we are already working through fixes for these issues which will make it into the final product.

    Martyn Lovell
    Development Lead
    Visual C++ Libraries

  • Chad C.

    Eugene,

    /D_SECURE_SCL=0 does exactly what I need.

    Thanks,
    Keith

  • Why is VC8 code much slower than VC7.1?