// ********************************************************************** // // Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. // // This copy of Ice is licensed to you under the terms described in the // ICE_LICENSE file included in this distribution. // // ********************************************************************** #include #include #include #include #include #include #include #include using namespace IceUtil; using namespace std; static StaticMutex staticMutex = ICE_STATIC_MUTEX_INITIALIZER; inline void usage(const char* myName) { cerr << "Usage: " << myName << " [number of UUIDs to generate] [number of threads]" << endl; } template class InsertThread : public Thread { public: typedef set ItemSet; InsertThread(int threadId, ItemSet& itemSet, GenerateFunc func, long howMany, bool verbose) : _threadId(threadId), _itemSet(itemSet), _func(func), _howMany(howMany), _verbose(verbose) { } void run() { for(long i = 0; i < _howMany; i++) { T item = _func(); StaticMutex::Lock lock(staticMutex); #if defined(_MSC_VER) && (_MSC_VER < 1300) pair ok = _itemSet.insert(item); #else pair ok = _itemSet.insert(item); #endif if(!ok.second) { cerr << "******* iteration " << i << endl; cerr << "******* Duplicate item: " << *ok.first << endl; } test(ok.second); if(_verbose && i > 0 && (i % 100000 == 0)) { cout << "Thread " << _threadId << ": generated " << i << " UUIDs." << endl; } } } private: int _threadId; ItemSet& _itemSet; GenerateFunc _func; long _howMany; bool _verbose; }; struct GenerateUUID { string operator()() { return generateUUID(); } }; struct GenerateRandomString { string operator()() { string s; s.resize(20); char buf[20]; IceUtilInternal::generateRandom(buf, static_cast(sizeof(buf))); for(unsigned int i = 0; i < sizeof(buf); ++i) { s[i] = 33 + buf[i] % (127-33); // We use ASCII 33-126 (from ! to ~, w/o space). } return s; } }; IceUtil::StaticMutex lock; struct GenerateRandomInt { public: int operator()() { return IceUtilInternal::random(); } }; template void runTest(int threadCount, GenerateFunc func, long howMany, bool verbose, string name) { cout << "Generating " << howMany << " " << name << "s using " << threadCount << " thread"; if(threadCount > 1) { cout << "s"; } cout << "... "; if(verbose) { cout << endl; } else { cout << flush; } set itemSet; vector threads; Time start = Time::now(); for(int i = 0; i < threadCount; i++) { ThreadPtr t = new InsertThread(i, itemSet, func, howMany / threadCount, verbose); threads.push_back(t->start()); } for(vector::iterator p = threads.begin(); p != threads.end(); ++p) { p->join(); } Time finish = Time::now(); cout << "ok" << endl; if(verbose) { cout << "Each " << name << " took an average of " << (double) ((finish - start).toMicroSeconds()) / howMany << " micro seconds to generate and insert into a set." << endl; } } int main(int argc, char* argv[]) { long howMany = 300000; int threadCount = 3; bool verbose = false; if(argc > 3) { usage(argv[0]); return EXIT_FAILURE; } else if(argc == 3) { howMany = atol(argv[1]); if (howMany == 0) { usage(argv[0]); return EXIT_FAILURE; } threadCount = atoi(argv[2]); if(threadCount <= 0) { usage(argv[0]); return EXIT_FAILURE; } verbose = true; } else if(argc == 2) { howMany = atol(argv[1]); if (howMany == 0) { usage(argv[0]); return EXIT_FAILURE; } } runTest(threadCount, GenerateUUID(), howMany, verbose, "UUID"); runTest(threadCount, GenerateRandomString(), howMany, verbose, "string"); return EXIT_SUCCESS; }