Poor performance from stdext::hash_map

Tech-Archive recommends: Speed Up your PC by fixing your registry

From: Andy Coates (nothanks_at_nowhere.com)
Date: 06/11/04

  • Next message: P.J. Plauger: "Re: Poor performance from stdext::hash_map"
    Date: Fri, 11 Jun 2004 12:38:02 +0100
    
    

    Hi,

    I've just noticed that MS are now shipping hash_map and hash_set with
    DevStudio. However, I'm finding that I'm getting worse performance than the
    standard map container and a lot worse than the MFC CMap. So I'm assuming
    I'm doing something wrong!

    Here's the code snipet - any help would be greatly appreciated:

    void DoMFCSTLCompare()
    {
         typedef CMap<CString, const TCHAR*, long, long> MFCMap;
         typedef std::map<std::string, long> STLMap;
         typedef stdext::hash_map<std::string, long> STLExtMap;

         const unsigned long nNumValues = 10000;

         long l;
         CString strMFC;
         std::string strSTL;

        // Init some strings:
         CString strMFC_Init[10000];
         std::string strSTL_Init[10000];
         for (unsigned long i = 0; i != nNumValues; ++i)
         {
              strMFC.Format(_T("Hello world %d"), i);
              strMFC_Init[i] = strMFC;
              strSTL_Init[i] = strMFC;
         }

         // STL version:
         const unsigned long nSTLStartTic = ::GetTickCount();
         STLMap stlMap;

         for (unsigned long i = 0; i != nNumValues; ++i)
              stlMap.insert(std::make_pair(strSTL_Init[i], i));

         const unsigned long nSTLInsertEndTic = ::GetTickCount();

         const STLMap::const_iterator itEnd = stlMap.end();
         for (STLMap::const_iterator it = stlMap.begin(); it != itEnd; ++it)
              ;

         const unsigned long nSTLExtractEndTic = ::GetTickCount();

         for (unsigned long i = 0; i != nNumValues; ++i)
              assert(stlMap.find(strSTL_Init[i]) != stlMap.end());

         const unsigned long nSTLSearchEndTic = ::GetTickCount();

         // STLExt version:
         const unsigned long nSTLExtStartTic = ::GetTickCount();
         STLExtMap stlextMap;

         for (unsigned long i = 0; i != nNumValues; ++i)
              stlextMap.insert(std::make_pair(strSTL_Init[i], i));

         const unsigned long nSTLExtInsertEndTic = ::GetTickCount();

         const STLExtMap::const_iterator itEnd2 = stlextMap.end();
         for (STLExtMap::const_iterator it2 = stlextMap.begin(); it2 != itEnd2;
    ++it2)
              ;

         const unsigned long nSTLExtExtractEndTic = ::GetTickCount();

         for (unsigned long i = 0; i != nNumValues; ++i)
              assert(stlextMap.find(strSTL_Init[i]) != stlextMap.end());

         const unsigned long nSTLExtSearchEndTic = ::GetTickCount();

         // MFC version:
         const unsigned long nMFCStartTic = ::GetTickCount();
         MFCMap mfcMap;
         mfcMap.InitHashTable(12007);

         for (unsigned long i = 0; i != nNumValues; ++i)
              mfcMap.SetAt(strMFC_Init[i], i);

         const unsigned long nMFCInsertEndTic = ::GetTickCount();

         POSITION pos = mfcMap.GetStartPosition();
         while (pos != 0)
              mfcMap.GetNextAssoc(pos, strMFC, l);

         const unsigned long nMFCExtractEndTic = ::GetTickCount();

         for (unsigned long i = 0; i != nNumValues; ++i)
              assert(mfcMap.Lookup(strMFC_Init[i], l) == TRUE);

         const unsigned long nMFCSearchEndTic = ::GetTickCount();
    }

    If I run this on .Net 2003 I get the following times (Debug build):

     nMFCInsertEndTic - nMFCStartTic 94 (MFC
    Insert)
     nMFCExtractEndTic - nMFCInsertEndTic 16 (MFC Iterate)
     nMFCSearchEndTic - nMFCExtractEndTic 41 (MFC Search)
     nSTLInsertEndTic - nSTLStartTic 734 (STL
    Insert)
     nSTLExtractEndTic - nSTLInsertEndTic 16 (STL
    Iterate)
     nSTLSearchEndTic - nSTLExtractEndTic 235 (STL Search)
     nSTLExtInsertEndTic - nSTLExtStartTic 2531 (STLExt
    Insert)
     nSTLExtExtractEndTic - nSTLExtInsertEndTic 0 (STLExt
    Iterate)
     nSTLExtSearchEndTic - nSTLExtExtractEndTic 11687 (STLExt Search)

    If I remove the InitHashMap call for the MFC version I get a slightly higher
    time, but still much quicker than the std::map (as expected as CMap is a
    hash container). What does puzzel me is the hash_map times.

    I'm knocking up a coding standards document and I'm a big fan of the STL, so
    I'd like to be able to recommend the STL containers over their MFC
    conterparts; but as it stands I won't be able to do that.

    Thanks for any help,

    Andy


  • Next message: P.J. Plauger: "Re: Poor performance from stdext::hash_map"

    Relevant Pages

    • Events Issue
      ... I'm hosting this on a dotnet container and mfc container(via com interop). ...
      (microsoft.public.dotnet.framework.interop)
    • Re: Von CList ableiten
      ... oversized List-Map oder die MFC Container. ... Du kannst eigene Container schreiben aber darfst nicht ... // Iterator intern ... CListIterator<int> iter; ...
      (microsoft.public.de.vc)
    • Re: std::map
      ... >> I can assume that you're using MFC. ... >> should use MFC collection classes. ... In case of exception MFC acknowledged exception type is ... Container self-validation in runtime for free. ...
      (microsoft.public.vc.language)
    • Interop Events Issue.
      ... I have a dot net control which raises an event with 2 string arguments. ... I'm hosting this on a dotnet container and mfc container(via com interop). ...
      (microsoft.public.dotnet.languages.csharp)
    • Re: [VS2008 SP1][std::vector] _CRT_DEBUGGER_HOOK crash in Release mode only -- [SOLVED by wo
      ... Giovanni suggestion earlier to move the data storage into the class but changed the container to std::list instead. ... My understanding is that, considering that STL containers like vector have no virtual destructor, it is better to use them via embedding than inheritance. ... In cases like this, my idea is that the probability that the bug is in my code is 99.99%, and that the bug is in Microsoft code is 0.01%:) ... I would focus the attention to CString. ...
      (microsoft.public.vc.language)