172 lines
4.2 KiB
C++
172 lines
4.2 KiB
C++
// Filename: test_map.cxx
|
|
// Created by: drose (29Sep04)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
|
//
|
|
// All use of this software is subject to the terms of the Panda 3d
|
|
// Software license. You should have received a copy of this license
|
|
// along with this source code; you will also find a current copy of
|
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
|
//
|
|
// To contact the maintainers of this program write to
|
|
// panda3d-general@lists.sourceforge.net .
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#include "pandabase.h"
|
|
#include "pmap.h"
|
|
#include "memoryUsage.h"
|
|
#include "clockObject.h"
|
|
|
|
class Alpha {
|
|
public:
|
|
Alpha(const string &str) : _str(str) { }
|
|
|
|
size_t get_hash() const {
|
|
size_t hash = 0;
|
|
string::const_iterator si;
|
|
for (si = _str.begin(); si != _str.end(); ++si) {
|
|
hash = (hash * 31) + (size_t)(*si);
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
bool operator < (const Alpha &other) const {
|
|
return strcmp(_str.c_str(), other._str.c_str()) < 0;
|
|
}
|
|
|
|
string _str;
|
|
};
|
|
|
|
ostream &operator << (ostream &out, const Alpha &alpha) {
|
|
return out << alpha._str;
|
|
}
|
|
|
|
class Beta : public Alpha {
|
|
public:
|
|
Beta(const string &str) : Alpha(str) { }
|
|
|
|
size_t get_hash() const {
|
|
return ~_str[0];
|
|
}
|
|
};
|
|
|
|
|
|
static const char * const sample_strings[] = {
|
|
"apple",
|
|
"apricot",
|
|
"banana",
|
|
"blueberry",
|
|
"grape",
|
|
"grapefruit",
|
|
"guava",
|
|
"honeydew",
|
|
"lemon",
|
|
"lime",
|
|
"mango",
|
|
"orange",
|
|
"peach",
|
|
"pear",
|
|
"pineapple",
|
|
"plum",
|
|
"raspberry",
|
|
"strawberry",
|
|
"watermelon",
|
|
};
|
|
static const size_t num_sample_strings = sizeof(sample_strings) / sizeof(const char *);
|
|
|
|
void
|
|
insert_fruit() {
|
|
// typedef pmap<Alpha, string> MapType;
|
|
// typedef pmap<Beta, string> MapType;
|
|
// typedef phash_map<Alpha, string> MapType;
|
|
typedef phash_map<Beta, string> MapType;
|
|
|
|
MapType m;
|
|
|
|
for (size_t i = 0; i < num_sample_strings; i++) {
|
|
string str = sample_strings[i];
|
|
bool inserted = m.insert(MapType::value_type(str, str)).second;
|
|
if (!inserted) {
|
|
cerr << "Could not insert " << str << "\n";
|
|
}
|
|
}
|
|
|
|
cout << "Map contains:\n";
|
|
MapType::iterator mi;
|
|
for (mi = m.begin(); mi != m.end(); ++mi) {
|
|
cout << " " << (*mi).first << "\n";
|
|
}
|
|
}
|
|
|
|
void
|
|
test_performance() {
|
|
typedef Alpha KeyType;
|
|
|
|
typedef phash_map<KeyType, int> MapType;
|
|
//typedef pmap<KeyType, int> MapType;
|
|
|
|
MemoryUsage::is_tracking();
|
|
ClockObject *clock = ClockObject::get_global_clock();
|
|
|
|
static const int key_len = 10;
|
|
static const int sample_mask = 0xffff;
|
|
static const int sample_size = sample_mask + 1;
|
|
static const int initial_population = 1000;
|
|
static const int num_cycles = 10000;
|
|
static const int num_reps = 3;
|
|
|
|
vector<KeyType> samples;
|
|
samples.reserve(sample_size);
|
|
for (int s = 0; s < sample_size; s++) {
|
|
string key;
|
|
for (int k = 0; k < key_len; k++) {
|
|
key += string(1, (char)((rand() & 0x3f) + '@'));
|
|
}
|
|
samples.push_back(key);
|
|
}
|
|
|
|
MemoryUsage::freeze();
|
|
MapType *m = new MapType;
|
|
if (MemoryUsage::has_cpp_size()) {
|
|
cerr << "Empty map uses " << MemoryUsage::get_current_cpp_size()
|
|
<< " bytes.\n";
|
|
}
|
|
|
|
for (int p = 0; p < initial_population; p++) {
|
|
m->insert(MapType::value_type(samples[rand() & sample_mask], 0));
|
|
}
|
|
if (MemoryUsage::has_cpp_size()) {
|
|
cerr << "map with " << m->size()
|
|
<< " elements uses " << MemoryUsage::get_current_cpp_size()
|
|
<< " bytes.\n";
|
|
}
|
|
|
|
for (int r = 0; r < num_reps; r++) {
|
|
double now = clock->get_real_time();
|
|
for (int c = 0; c < num_cycles; c++) {
|
|
const KeyType &element = samples[rand() & sample_mask];
|
|
bool inserted = m->insert(MapType::value_type(element, 0)).second;
|
|
if (inserted) {
|
|
m->erase(element);
|
|
}
|
|
}
|
|
double elapsed = clock->get_real_time() - now;
|
|
cerr << "After " << num_cycles << " cycles in " << elapsed * 1000.0
|
|
<< " ms, map has " << m->size()
|
|
<< " elements and uses " << MemoryUsage::get_current_cpp_size()
|
|
<< " bytes.\n";
|
|
}
|
|
}
|
|
|
|
int
|
|
main(int argc, char *argv[]) {
|
|
// insert_fruit();
|
|
test_performance();
|
|
|
|
return 0;
|
|
}
|