Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map performance issue

If someone could help me out, I'm completely out of ideas.

So I have this code (it's a very simplified version of my code):

while(readNewFile())
{
    while(getNewStructFromFile())
    {
        unsigned long starttime = GetTickCount();
        customerData.fillFromBinaryData(structPointer);
        cout<< GetTickCount() - starttime;

        aMap.insert(pair<int,string>(customerData.phoneNumber,""));
    }

    // Ouptut all data

    aMap.clear();
}

Basically, it just reads records from a binary file. customerData get's the data and fills its variables with data from it. Then, it inserts the phone number into a map (for debugging I am really just inserting an int and an empty string).

The problem is, that after a short while this program gets very slow; if I comment out the map insert the program runs OK without problems with a constant execution time per file. If I use the map insertion, after a few files, the program again goes very slow (from 8 - 10 seconds to 1 minute or more). But debugging with GetTickCount(), it shows me that the delay happens in customerData.fillFromBinaryData (at first 0ms, and then it jumps to 30-40 ms (for filling out the class variables)). But if I comment this simple map insertion, there is no delay in filling the object with data! Where is the logic in that? Could someone give me a hint, I am out of ideas. Sorry if this question is not a really good one.

I tried different types of maps, but again, it shows me that the delay is not in the map insertion.

Edit/Possible solution:

In case someone has similar issues, I installed VS2015, and the delay using maps is gone! I am not sure how this is related, but Hurray!

like image 726
Silencer Avatar asked Nov 09 '22 07:11

Silencer


1 Answers

It might happen, that if a map grows very big, you have a problem with memory management and fillFromBinaryData requires some memory allocation which is now slower. Due to a memory fragmentation maybe?

I would suggest to try some libraries for this specific purpose. However, I forgot how they are called. I just know that there is one available from Google, "jemalloc" or something similar.

The main point of a custom memory pool is that you can allocate memory once as a big bunch, and use it only in a scope of your app with custom allocators.

One more thing is maybe to stop to use a map and use the unordered map instead. Change the time complexity for insertion from O(logn) to O(1) with a perfect hash function, since for you, is a phone number.

  • It is called jemalloc and it is not from Google. :)
like image 91
AlexTheo Avatar answered Nov 15 '22 10:11

AlexTheo