diff options
author | Anton Samokhvalov <pg83@yandex.ru> | 2022-02-10 16:45:17 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:17 +0300 |
commit | d3a398281c6fd1d3672036cb2d63f842d2cb28c5 (patch) | |
tree | dd4bd3ca0f36b817e96812825ffaf10d645803f2 /library/cpp/threading/skip_list/perf/main.cpp | |
parent | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff) | |
download | ydb-d3a398281c6fd1d3672036cb2d63f842d2cb28c5.tar.gz |
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/threading/skip_list/perf/main.cpp')
-rw-r--r-- | library/cpp/threading/skip_list/perf/main.cpp | 586 |
1 files changed, 293 insertions, 293 deletions
diff --git a/library/cpp/threading/skip_list/perf/main.cpp b/library/cpp/threading/skip_list/perf/main.cpp index d722d43436..4ad52049e7 100644 --- a/library/cpp/threading/skip_list/perf/main.cpp +++ b/library/cpp/threading/skip_list/perf/main.cpp @@ -14,345 +14,345 @@ #include <util/system/thread.h> namespace { - using namespace NThreading; + using namespace NThreading; - //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// IOutputStream& LogInfo() { - return Cerr << TInstant::Now() << " INFO: "; - } + return Cerr << TInstant::Now() << " INFO: "; + } IOutputStream& LogError() { - return Cerr << TInstant::Now() << " ERROR: "; - } - - //////////////////////////////////////////////////////////////////////////////// - - struct TListItem { - TStringBuf Key; - TStringBuf Value; - - TListItem(const TStringBuf& key, const TStringBuf& value) - : Key(key) - , Value(value) - { - } - - int Compare(const TListItem& other) const { - return Key.compare(other.Key); - } - }; - - using TListType = TSkipList<TListItem>; - - //////////////////////////////////////////////////////////////////////////////// - - class TRandomData { - private: - TVector<char> Buffer; - - public: - TRandomData() - : Buffer(1024 * 1024) - { - for (size_t i = 0; i < Buffer.size(); ++i) { - Buffer[i] = RandomNumber<char>(); - } - } - - TStringBuf GetString(size_t len) const { - size_t start = RandomNumber(Buffer.size() - len); - return TStringBuf(&Buffer[start], len); + return Cerr << TInstant::Now() << " ERROR: "; + } + + //////////////////////////////////////////////////////////////////////////////// + + struct TListItem { + TStringBuf Key; + TStringBuf Value; + + TListItem(const TStringBuf& key, const TStringBuf& value) + : Key(key) + , Value(value) + { + } + + int Compare(const TListItem& other) const { + return Key.compare(other.Key); + } + }; + + using TListType = TSkipList<TListItem>; + + //////////////////////////////////////////////////////////////////////////////// + + class TRandomData { + private: + TVector<char> Buffer; + + public: + TRandomData() + : Buffer(1024 * 1024) + { + for (size_t i = 0; i < Buffer.size(); ++i) { + Buffer[i] = RandomNumber<char>(); + } + } + + TStringBuf GetString(size_t len) const { + size_t start = RandomNumber(Buffer.size() - len); + return TStringBuf(&Buffer[start], len); + } + + TStringBuf GetString(size_t min, size_t max) const { + return GetString(min + RandomNumber(max - min)); } + }; - TStringBuf GetString(size_t min, size_t max) const { - return GetString(min + RandomNumber(max - min)); - } - }; - - //////////////////////////////////////////////////////////////////////////////// - - class TWorkerThread: public ISimpleThread { - private: - std::function<void()> Func; - TDuration Time; - - public: - TWorkerThread(std::function<void()> func) - : Func(func) - { - } - - TDuration GetTime() const { - return Time; - } - - private: - void* ThreadProc() noexcept override { - TInstant started = TInstant::Now(); - Func(); - Time = TInstant::Now() - started; - return nullptr; - } - }; - - inline TAutoPtr<TWorkerThread> StartThread(std::function<void()> func) { - TAutoPtr<TWorkerThread> thread = new TWorkerThread(func); - thread->Start(); - return thread; + //////////////////////////////////////////////////////////////////////////////// + + class TWorkerThread: public ISimpleThread { + private: + std::function<void()> Func; + TDuration Time; + + public: + TWorkerThread(std::function<void()> func) + : Func(func) + { + } + + TDuration GetTime() const { + return Time; + } + + private: + void* ThreadProc() noexcept override { + TInstant started = TInstant::Now(); + Func(); + Time = TInstant::Now() - started; + return nullptr; + } + }; + + inline TAutoPtr<TWorkerThread> StartThread(std::function<void()> func) { + TAutoPtr<TWorkerThread> thread = new TWorkerThread(func); + thread->Start(); + return thread; } - //////////////////////////////////////////////////////////////////////////////// - - typedef std::function<void()> TTestFunc; - - struct TTest { - TString Name; - TTestFunc Func; - - TTest() { - } - - TTest(const TString& name, const TTestFunc& func) - : Name(name) - , Func(func) - { - } - }; - - //////////////////////////////////////////////////////////////////////////////// - - class TTestSuite { - private: - size_t Iterations = 1000000; - size_t KeyLen = 10; - size_t ValueLen = 100; - size_t NumReaders = 4; - size_t NumWriters = 1; - size_t BatchSize = 20; - - TMemoryPool MemoryPool; - TListType List; - TMutex Mutex; - TRandomData Random; - - TMap<TCiString, TTest> AllTests; - TVector<TTest> Tests; - - public: - TTestSuite() - : MemoryPool(64 * 1024) - , List(MemoryPool) - { - } - - bool Init(int argc, const char* argv[]) { - TVector<TString> tests; - try { - NLastGetopt::TOpts opts; - opts.AddHelpOption(); - -#define OPTION(opt, x) \ - opts.AddLongOption(opt, #x) \ - .Optional() \ - .DefaultValue(ToString(x)) \ - .StoreResult(&x) // end of OPTION - - OPTION('i', Iterations); - OPTION('k', KeyLen); - OPTION('v', ValueLen); - OPTION('r', NumReaders); - OPTION('w', NumWriters); - OPTION('b', BatchSize); + //////////////////////////////////////////////////////////////////////////////// + + typedef std::function<void()> TTestFunc; + + struct TTest { + TString Name; + TTestFunc Func; + + TTest() { + } + + TTest(const TString& name, const TTestFunc& func) + : Name(name) + , Func(func) + { + } + }; + + //////////////////////////////////////////////////////////////////////////////// + + class TTestSuite { + private: + size_t Iterations = 1000000; + size_t KeyLen = 10; + size_t ValueLen = 100; + size_t NumReaders = 4; + size_t NumWriters = 1; + size_t BatchSize = 20; + + TMemoryPool MemoryPool; + TListType List; + TMutex Mutex; + TRandomData Random; + + TMap<TCiString, TTest> AllTests; + TVector<TTest> Tests; + + public: + TTestSuite() + : MemoryPool(64 * 1024) + , List(MemoryPool) + { + } + + bool Init(int argc, const char* argv[]) { + TVector<TString> tests; + try { + NLastGetopt::TOpts opts; + opts.AddHelpOption(); + +#define OPTION(opt, x) \ + opts.AddLongOption(opt, #x) \ + .Optional() \ + .DefaultValue(ToString(x)) \ + .StoreResult(&x) // end of OPTION + + OPTION('i', Iterations); + OPTION('k', KeyLen); + OPTION('v', ValueLen); + OPTION('r', NumReaders); + OPTION('w', NumWriters); + OPTION('b', BatchSize); #undef OPTION - NLastGetopt::TOptsParseResultException optsRes(&opts, argc, argv); - for (const auto& opt : opts.Opts_) { - const NLastGetopt::TOptParseResult* r = optsRes.FindOptParseResult(opt.Get(), true); - if (r) { - LogInfo() << "[-" << opt->GetChar() << "] " << opt->GetName() << ": " << r->Back() << Endl; - } + NLastGetopt::TOptsParseResultException optsRes(&opts, argc, argv); + for (const auto& opt : opts.Opts_) { + const NLastGetopt::TOptParseResult* r = optsRes.FindOptParseResult(opt.Get(), true); + if (r) { + LogInfo() << "[-" << opt->GetChar() << "] " << opt->GetName() << ": " << r->Back() << Endl; + } } - tests = optsRes.GetFreeArgs(); - } catch (...) { - LogError() << CurrentExceptionMessage() << Endl; - return false; + tests = optsRes.GetFreeArgs(); + } catch (...) { + LogError() << CurrentExceptionMessage() << Endl; + return false; } #define TEST(type) \ - AddTest(#type, std::bind(&TTestSuite::Y_CAT(TEST_, type), this)) // end of TEST + AddTest(#type, std::bind(&TTestSuite::Y_CAT(TEST_, type), this)) // end of TEST - TEST(Clear); - TEST(InsertRandom); - TEST(InsertSequential); - TEST(InsertSequentialSimple); - TEST(LookupRandom); - TEST(Concurrent); + TEST(Clear); + TEST(InsertRandom); + TEST(InsertSequential); + TEST(InsertSequentialSimple); + TEST(LookupRandom); + TEST(Concurrent); #undef TEST - if (tests.empty()) { - LogError() << "no tests specified, choose from: " << PrintTests() << Endl; + if (tests.empty()) { + LogError() << "no tests specified, choose from: " << PrintTests() << Endl; return false; } - - for (size_t i = 0; i < tests.size(); ++i) { + + for (size_t i = 0; i < tests.size(); ++i) { if (!AllTests.contains(tests[i])) { - LogError() << "unknown test name: " << tests[i] << Endl; - return false; - } - Tests.push_back(AllTests[tests[i]]); - } - - return true; + LogError() << "unknown test name: " << tests[i] << Endl; + return false; + } + Tests.push_back(AllTests[tests[i]]); + } + + return true; } - void Run() { + void Run() { #if !defined(NDEBUG) - LogInfo() << "*** DEBUG build! ***" << Endl; + LogInfo() << "*** DEBUG build! ***" << Endl; #endif - for (const TTest& test : Tests) { - LogInfo() << "Starting test " << test.Name << Endl; - - TInstant started = TInstant::Now(); - try { - test.Func(); - } catch (...) { - LogError() << "test " << test.Name - << " failed: " << CurrentExceptionMessage() - << Endl; - } - - LogInfo() << "List size = " << List.GetSize() << Endl; - - TDuration duration = TInstant::Now() - started; - LogInfo() << "test " << test.Name - << " duration: " << duration - << " (" << (double)duration.MicroSeconds() / (Iterations * NumWriters) << "us per iteration)" - << Endl; - LogInfo() << "Finished test " << test.Name << Endl; - } + for (const TTest& test : Tests) { + LogInfo() << "Starting test " << test.Name << Endl; + + TInstant started = TInstant::Now(); + try { + test.Func(); + } catch (...) { + LogError() << "test " << test.Name + << " failed: " << CurrentExceptionMessage() + << Endl; + } + + LogInfo() << "List size = " << List.GetSize() << Endl; + + TDuration duration = TInstant::Now() - started; + LogInfo() << "test " << test.Name + << " duration: " << duration + << " (" << (double)duration.MicroSeconds() / (Iterations * NumWriters) << "us per iteration)" + << Endl; + LogInfo() << "Finished test " << test.Name << Endl; + } + } + + private: + void AddTest(const char* name, TTestFunc func) { + AllTests[name] = TTest(name, func); } - private: - void AddTest(const char* name, TTestFunc func) { - AllTests[name] = TTest(name, func); - } - - TString PrintTests() const { - TVector<TString> names; - for (const auto& it : AllTests) { - names.push_back(it.first); - } - return JoinSeq(", ", names); + TString PrintTests() const { + TVector<TString> names; + for (const auto& it : AllTests) { + names.push_back(it.first); + } + return JoinSeq(", ", names); } - void TEST_Clear() { - List.Clear(); - } + void TEST_Clear() { + List.Clear(); + } - void TEST_InsertRandom() { - for (size_t i = 0; i < Iterations; ++i) { - List.Insert(TListItem(Random.GetString(KeyLen), Random.GetString(ValueLen))); - } + void TEST_InsertRandom() { + for (size_t i = 0; i < Iterations; ++i) { + List.Insert(TListItem(Random.GetString(KeyLen), Random.GetString(ValueLen))); + } } - void TEST_InsertSequential() { - TString key; - for (size_t i = 0; i < Iterations;) { - key.assign(Random.GetString(KeyLen)); - size_t batch = BatchSize / 2 + RandomNumber(BatchSize); - for (size_t j = 0; j < batch; ++j, ++i) { - key.resize(KeyLen - 1); - key.append((char)j); - List.Insert(TListItem(key, Random.GetString(ValueLen))); - } + void TEST_InsertSequential() { + TString key; + for (size_t i = 0; i < Iterations;) { + key.assign(Random.GetString(KeyLen)); + size_t batch = BatchSize / 2 + RandomNumber(BatchSize); + for (size_t j = 0; j < batch; ++j, ++i) { + key.resize(KeyLen - 1); + key.append((char)j); + List.Insert(TListItem(key, Random.GetString(ValueLen))); + } } } - void TEST_InsertSequentialSimple() { - for (size_t i = 0; i < Iterations; ++i) { - List.Insert(TListItem(Random.GetString(KeyLen), Random.GetString(ValueLen))); - } + void TEST_InsertSequentialSimple() { + for (size_t i = 0; i < Iterations; ++i) { + List.Insert(TListItem(Random.GetString(KeyLen), Random.GetString(ValueLen))); + } } - void TEST_LookupRandom() { - for (size_t i = 0; i < Iterations; ++i) { - List.SeekTo(TListItem(Random.GetString(KeyLen), TStringBuf())); - } + void TEST_LookupRandom() { + for (size_t i = 0; i < Iterations; ++i) { + List.SeekTo(TListItem(Random.GetString(KeyLen), TStringBuf())); + } } - void TEST_Concurrent() { - LogInfo() << "starting producers..." << Endl; - - TVector<TAutoPtr<TWorkerThread>> producers(NumWriters); - for (size_t i1 = 0; i1 < producers.size(); ++i1) { - producers[i1] = StartThread([&] { - TInstant started = TInstant::Now(); - for (size_t i2 = 0; i2 < Iterations; ++i2) { - { - TGuard<TMutex> guard(Mutex); - List.Insert(TListItem(Random.GetString(KeyLen), Random.GetString(ValueLen))); - } + void TEST_Concurrent() { + LogInfo() << "starting producers..." << Endl; + + TVector<TAutoPtr<TWorkerThread>> producers(NumWriters); + for (size_t i1 = 0; i1 < producers.size(); ++i1) { + producers[i1] = StartThread([&] { + TInstant started = TInstant::Now(); + for (size_t i2 = 0; i2 < Iterations; ++i2) { + { + TGuard<TMutex> guard(Mutex); + List.Insert(TListItem(Random.GetString(KeyLen), Random.GetString(ValueLen))); + } + } + TDuration duration = TInstant::Now() - started; + LogInfo() + << "Average time for producer = " + << (double)duration.MicroSeconds() / Iterations << "us per iteration" + << Endl; + }); + } + + LogInfo() << "starting consumers..." << Endl; + + TVector<TAutoPtr<TWorkerThread>> consumers(NumReaders); + for (size_t i1 = 0; i1 < consumers.size(); ++i1) { + consumers[i1] = StartThread([&] { + TInstant started = TInstant::Now(); + for (size_t i2 = 0; i2 < Iterations; ++i2) { + List.SeekTo(TListItem(Random.GetString(KeyLen), TStringBuf())); } - TDuration duration = TInstant::Now() - started; - LogInfo() - << "Average time for producer = " - << (double)duration.MicroSeconds() / Iterations << "us per iteration" - << Endl; - }); - } - - LogInfo() << "starting consumers..." << Endl; - - TVector<TAutoPtr<TWorkerThread>> consumers(NumReaders); - for (size_t i1 = 0; i1 < consumers.size(); ++i1) { - consumers[i1] = StartThread([&] { - TInstant started = TInstant::Now(); - for (size_t i2 = 0; i2 < Iterations; ++i2) { - List.SeekTo(TListItem(Random.GetString(KeyLen), TStringBuf())); - } - TDuration duration = TInstant::Now() - started; - LogInfo() - << "Average time for consumer = " - << (double)duration.MicroSeconds() / Iterations << "us per iteration" - << Endl; - }); - } - - LogInfo() << "wait for producers..." << Endl; - - TDuration producerTime; - for (size_t i = 0; i < producers.size(); ++i) { - producers[i]->Join(); - producerTime += producers[i]->GetTime(); - } - - LogInfo() << "wait for consumers..." << Endl; - - TDuration consumerTime; - for (size_t i = 0; i < consumers.size(); ++i) { - consumers[i]->Join(); - consumerTime += consumers[i]->GetTime(); - } - - LogInfo() << "average producer time: " - << producerTime.SecondsFloat() / producers.size() << " seconds" - << Endl; - - LogInfo() << "average consumer time: " - << consumerTime.SecondsFloat() / consumers.size() << " seconds" - << Endl; - } - }; - -} + TDuration duration = TInstant::Now() - started; + LogInfo() + << "Average time for consumer = " + << (double)duration.MicroSeconds() / Iterations << "us per iteration" + << Endl; + }); + } + + LogInfo() << "wait for producers..." << Endl; + + TDuration producerTime; + for (size_t i = 0; i < producers.size(); ++i) { + producers[i]->Join(); + producerTime += producers[i]->GetTime(); + } + + LogInfo() << "wait for consumers..." << Endl; + + TDuration consumerTime; + for (size_t i = 0; i < consumers.size(); ++i) { + consumers[i]->Join(); + consumerTime += consumers[i]->GetTime(); + } + + LogInfo() << "average producer time: " + << producerTime.SecondsFloat() / producers.size() << " seconds" + << Endl; + + LogInfo() << "average consumer time: " + << consumerTime.SecondsFloat() / consumers.size() << " seconds" + << Endl; + } + }; + +} //////////////////////////////////////////////////////////////////////////////// -int main(int argc, const char* argv[]) { +int main(int argc, const char* argv[]) { TTestSuite suite; if (!suite.Init(argc, argv)) { return -1; |