Skip to Main Content

Integration

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

C++ Hashtable container performance

890486Nov 1 2011 — edited Nov 23 2011
I found interesting behaviour of C++ Hashtable container.

To demonsteate this, let’s cosider the following example:
We have got 100 000 of keys and values that we will be adding to Hashtable and measure how long it takes.
Both key and value are plain C string (char*). Please see source code bellow in the post.

In the degug build I am getting following output

Adding to map 100000 items took 1.469 seconds
Adding to map 100000 items took 1.954 seconds
Adding to map 100000 items took 1.954 seconds
Adding to map 100000 items took 1.954 seconds
Adding to map 100000 items took 1.953 seconds
Adding to map 100000 items took 1.953 seconds
Adding to map 100000 items took 1.969 seconds


In the release build I am getting the following

Adding to map 100000 items took 1.359 seconds
Adding to map 100000 items took 2.766 seconds
Adding to map 100000 items took 2.687 seconds
Adding to map 100000 items took 2.719 seconds
Adding to map 100000 items took 2.718 seconds
Adding to map 100000 items took 2.719 seconds
Adding to map 100000 items took 2.718 seconds
Adding to map 100000 items took 2.735 seconds


My question here – why debug build performs significantly better then release?


There is another interesting thing here:
Let’s comment out the following line
coherenceMap->clear();

Now debug build produces a following lines:
Adding to map 100000 items took 1.5 seconds
Adding to map 100000 items took 1.422 seconds
Adding to map 100000 items took 1.422 seconds
Adding to map 100000 items took 1.421 seconds


And release
Adding to map 100000 items took 1.328 seconds
Adding to map 100000 items took 1.25 seconds
Adding to map 100000 items took 1.25 seconds
Adding to map 100000 items took 1.282 seconds
Adding to map 100000 items took 1.265 seconds

Now release builds as expected performs better then debug one.

Why removing all elements from map causing such performance degradation in release build?

This is synthetic example to demonstrate a problem. In my real application permanence difference even more dramatic 6 seconds in release builds vs 1.3 seconds in debug build.

I think poor performance of release builds relates to the calling of coherenceMap->clear() method. First batch of 100 000 gets added in 0.5 seconds and following(after coherenceMap->clear() called to remove previous elements) take 5-6 seconds.

Is it a known issue or can some one try my test application and confirm or reject my findings.


I am on Windows XP, Coherence 3.6 and Visual Studio 2005.

Test application source code

// CPPCoherenceTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <string>
#include <map>
#include <sstream>
#include <iostream>
#include<ctime>
#include<windows.h>
#include "TopicSnapReader.h"
#include "TopicSnap.h"


using namespace coherence::lang;
using coherence::net::CacheFactory;
using coherence::net::NamedCache;
using coherence::util::extractor::ReflectionExtractor;
using coherence::util::ValueExtractor;
using coherence::util::extractor::PofExtractor;
using coherence::util::filter::EqualsFilter;
using coherence::util::Filter;
using coherence::util::Iterator;
using coherence::util::extractor::KeyExtractor;
using coherence::util::Hashtable;
using coherence::util::HashSet;

std::map<std::string, std::string> testDataMap;
int snapSize = 100000;
char **keys;
char **values;



void generateTestData()
{
keys = new char*[snapSize];
values = new char*[snapSize];

std::stringstream strStream;
for (int i = 0; i < snapSize; ++i)
{
strStream.str("");
strStream << "key-" << i;
std::string key = strStream.str();
key.resize(250, '_');
strStream.str("");
strStream << "value-" << i;
std::string value = strStream.str();
value.resize(1024, '-');

keys[i] = new char[key.length() + 1];
strcpy(keys, key.c_str());

values[i] = new char[value.length() + 1];
strcpy(values[i], value.c_str());

}

}

int tmain(int argc, TCHAR* argv[])
{
HRESULT hr = CoInitializeEx( 0, COINIT_MULTITHREADED );
_ASSERT( SUCCEEDED( hr ) );
( hr );

generateTestData();
Map::Handle coherenceMap = Hashtable::create();

while (true)
{
coherenceMap->clear();
clock_t t1=clock();
for (int i = 0; i < snapSize; ++i)
{
coherenceMap->put(String::View(keys[i]), String::View(values[i]) );
}
clock_t t2=clock();
std::cout << "Adding to map " << snapSize << " items took " << double(t2-t1)/CLOCKS_PER_SEC << " seconds" << std::endl;
}



return 0;
}

Edited by: user2593443 on 01-Nov-2011 12:01
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Dec 21 2011
Added on Nov 1 2011
4 comments
198 views