2

Use the following code with your own timing code around the call to delete msg in main(). When running in debug mode, it is taking 473 times as long, on average, as when running without debugging. Does anyone know why this is happening? If so, is there a way that I can get this code to run much faster in debug mode?

Note: I am using Visual Studio 2008 SP 1 on a Windows 7 machine.

// This file is generated by using the Google Protocol Buffers compiler
// to compile a PropMsg.proto file (contents of that file are listed below)
#include "PropMsg.pb.h"

void RawSerializer::serialize(int i_val, PropMsg * o_msg)
{
        o_msg->set_v_int32(i_val);
}
void serialize(std::vector<int> const & i_val, PropMsg * o_msg)
{
    for (std::vector<int>::const_iterator it = i_val.begin(); it != i_val.end(); ++it) {
        PropMsg * objMsg = o_msg->add_v_var_repeated();
        serialize( * it, objMsg);
    }
}

int main()
{
    std::vector<int> testVec(100000);
    PropMsg * msg = new PropMsg;
    serialize(testVec, msg);
    delete msg; // Time this guy
}

PropMsg was created with the following .proto file definition:

option optimize_for = SPEED;
message PropMsg
{
  optional int32 v_int32 = 7;
  repeated PropMsg v_var_repeated = 101;
}

Here's some sample test output that I got:

datatype: class std::vector<int,class std::allocator<int> >
                               num runs:                   10
                              num items:               100000
        deserializing from PropMsg time:               0.0046
            serializing to PropMsg time:               0.0426
                 reading from disk time:               0.7195
                   writing to disk time:               0.0298
              deallocating PropMsg time:                 8.99

Notice how this is NOT IO-bound.

Chris Morris
  • 4,335
  • 4
  • 24
  • 28
  • Well, it is debugging mode, so it does extra things to catch bugs... – PlasmaHH Aug 07 '12 at 23:19
  • How accurate is your measurement? 100000 is not a huge number in our times. You should repeat the procedure in main many times. – Kirill Kobelev Aug 07 '12 at 23:21
  • What does `PropMsg.ph.h` contain? – Jesse Good Aug 07 '12 at 23:23
  • It is decently accurate. I run the test multiple times and average the result. And I ran more tests, but didn't show them here because I wanted to keep the question/info short. – Chris Morris Aug 07 '12 at 23:23
  • PropMsg.pb.h contains the definition of the PropMsg class, which is generated when the Google Protocol Buffers compiler compiles the .proto file. – Chris Morris Aug 07 '12 at 23:24
  • What was the point of even *measuring* that it was slower with 3 significant digits? Protocol buffers should always be I/O bound so it shouldn't matter. Certainly not something to give up the iterator debugging feature that makes it slow. – Hans Passant Aug 07 '12 at 23:26

1 Answers1

1

STL containers in VS Debug are notoriously slow. Game programmers forums are rife with complaints about this. Often people choose alternative implementations. However, from what I've read, you can get a performance boost up front by disabling iterator debugging/checking:

#define _HAS_ITERATOR_DEBUGGING 0
#define _SECURE_SCL 0

Other things that can affect debug performance are excessive calls to new and delete. Memory pools can help with that. You haven't provided details for PropMsg::add_v_var_repeated() or PropMsg::~PropMsg(), so I can't comment. But I assume there's a vector or other STL container inside that class?

paddy
  • 60,864
  • 6
  • 61
  • 103
  • Also, [this thread](http://stackoverflow.com/questions/1060337/why-does-my-stl-code-run-so-slowly-when-i-have-the-debugger-ide-attached) might be useful to you. – paddy Aug 07 '12 at 23:37
  • 1
    Yesterday, I thought that setting those two symbols to 0 fixed my issue. However, today, I ran my code and it is still slow. Following your link led to me trying defining the _NO_DEBUG_HEAP environment variable, which worked. However, I'd prefer to set some preprocessing symbols. Do you have any idea if those two pound defines should work (yes, I have verified that they are, indeed, being set and not overridden, at least I think...). – Chris Morris Aug 09 '12 at 00:10
  • Setting preprocessor symbols in project settings does the same thing as setting them in code, but if you do it in the compiler you don't have to worry about them not being set in any one source file. For some of these there may be check-boxes in the project settings user interface. Otherwise, adding them to the preprocessor definitions list is fine. To do it in code, make sure that you define them *before* including any of the C++ STL headers. If your project is native Visual Studio, you'll have `stdafx.h` which is helpful for this. – paddy Aug 09 '12 at 00:24
  • As for _NO_DEBUG_HEAP. As far as I'm aware it is only relevant when you have attached Debug code to Visual Studio. It seems to be an environment variable, not a preprocessor definition. Regardless of whether you have that environment variable set, if you run your Debug code outside of Visual Studio then apparently it should run fast. – paddy Aug 09 '12 at 00:26