From 2592f98296023cd6c98f3f50ceffc2d5c9a843f0 Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Thu, 21 Dec 2017 16:13:14 -0800 Subject: [PATCH] Add SSet implementation. --- src/Makefile.am | 4 +- src/list_bench.cc | 1 + src/ods/simpsset.h | 92 ++++++++++++++++++++++++++++++++++++++++++++++ src/ods/sset.h | 20 ++++++++++ src/sset_bench.cc | 86 +++++++++++++++++++++++++++++++++++++++++++ src/uset_bench.cc | 86 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 src/ods/simpsset.h create mode 100644 src/ods/sset.h create mode 100644 src/sset_bench.cc create mode 100644 src/uset_bench.cc diff --git a/src/Makefile.am b/src/Makefile.am index dd599d3..6e863e6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,10 +4,12 @@ AM_CPPFLAGS += -Wunused-variable -std=c++17 -D_XOPEN_SOURCE -O0 -g -I. AM_CPPFLAGS += -fno-elide-constructors -Weffc++ bin_PROGRAMS := ch01ex01 ch01ex03 ch01ex04 ch01ex05 ch01ex06 \ - list_bench + list_bench uset_bench sset_bench ch01ex01_SOURCES := ch01ex01.cc ch01ex03_SOURCES := ch01ex03.cc ch01ex04_SOURCES := ch01ex04.cc ch01ex05_SOURCES := ch01ex05.cc ch01ex06_SOURCES := ch01ex06.cc list_bench_SOURCES := list_bench.cc +uset_bench_SOURCES := uset_bench.cc +sset_bench_SOURCES := sset_bench.cc diff --git a/src/list_bench.cc b/src/list_bench.cc index 8811a9f..802f072 100644 --- a/src/list_bench.cc +++ b/src/list_bench.cc @@ -56,6 +56,7 @@ benchmark(ods::List& list, int ops) cout << "\tget " << j << endl; assert(list.get(j) != -1); + break; // set case 1: if (list.size() == 0) { diff --git a/src/ods/simpsset.h b/src/ods/simpsset.h new file mode 100644 index 0000000..ae24a55 --- /dev/null +++ b/src/ods/simpsset.h @@ -0,0 +1,92 @@ +#ifndef __ODS_ODS_SIMPSSET__ +#define __ODS_ODS_SIMPSSET__ + + +#include +#include +#include + +namespace ods { +template +class SimpSSet : public SSet { +public: + SimpSSet(void); + ~SimpSSet(void); + std::size_t size(void); + bool add(T); + std::optional remove(T); + std::optional find(T); +private: + SimpList list; +}; + +template +SimpSSet::SimpSSet() +{ +} + + +template +SimpSSet::~SimpSSet() +{ +} + +template +std::size_t +SimpSSet::size() +{ + return this->list.size(); +} + +template +bool +SimpSSet::add(T value) +{ + for (std::size_t i = 0; i < this->list.size(); i++) { + if (this->list.get(i) == value) { + return false; + } + } + + for (std::size_t i = 0; i < this->list.size(); i++) { + if (this->list.get(i) < value) { + continue; + } + this->list.add(i, value); + } + return true; +} + +template +std::optional +SimpSSet::remove(T value) +{ + for (std::size_t i = 0; i < this->list.size(); i++) { + if (this->list.get(i) == value) { + auto removed = this->list.get(i); + this->list.remove(i); + return removed; + } + } + + return std::nullopt; +} + +template +std::optional +SimpSSet::find(T value) +{ + for (std::size_t i = 0; i < this->list.size(); i++) { + if (this->list.get(i) == value) { + return this->list.get(i); + } + } + + return std::nullopt; +} + + +} // namespace ods + + +#endif // __ODS_ODS_SIMPSSET__ \ No newline at end of file diff --git a/src/ods/sset.h b/src/ods/sset.h new file mode 100644 index 0000000..aed3a2b --- /dev/null +++ b/src/ods/sset.h @@ -0,0 +1,20 @@ +#ifndef __ODS_ODS_SSET__ +#define __ODS_ODS_SSET__ + + +#include +#include + +namespace ods { +template +class SSet { +public: + virtual ~SSet(void) {}; + virtual std::size_t size(void) =0; + virtual bool add(T) = 0; + virtual std::optional remove(T) = 0; + virtual std::optional find(T) = 0; +}; +} // namespace ods + +#endif // __ODS_ODS_SSET__ \ No newline at end of file diff --git a/src/sset_bench.cc b/src/sset_bench.cc new file mode 100644 index 0000000..b907f2f --- /dev/null +++ b/src/sset_bench.cc @@ -0,0 +1,86 @@ +// list_bench runs benchmarks against List implementations. +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +static mt19937 rng; +static random_device devrand; + +// reseed picks a new seed for the RNG using the system random device. +static void +reseed() +{ + rng.seed(devrand()); +} + + +static int +randint(int low, int high) +{ + uniform_int_distribution dist(low, high); + return dist(rng); +} + +static void +benchmark(ods::SSet& set, int ops) +{ + for (int i = 0; i < ops; i++) { + auto op = randint(0, 3); + int val = randint(1, 100); + + switch (op) { + // add + case 0: + case 1: + cout << "\tadd " << val << endl; + set.add(val); + break; + // remove + case 2: + set.remove(val); + break; + // find + case 3: + set.find(val); + break; + } + } +} + + +static void +run(string label, ods::SSet& list, int ops) +{ + std::chrono::steady_clock clock; + + auto start = clock.now(); + benchmark(list, ops); + auto stop = clock.now(); + + std::chrono::duration delta = stop - start; + cerr << label << " @ " << ops << " ops: " << delta.count() << "s" << endl; +} + + +int +main(int argc, char *argv[]) +{ + int ops = 1000; + + if (argc == 2) { + ops = stoi(argv[1]); + } + + reseed(); + + ods::SimpSSet us; + run("SimpSSet", us, ops); + + return 0; +} \ No newline at end of file diff --git a/src/uset_bench.cc b/src/uset_bench.cc new file mode 100644 index 0000000..c89b2d7 --- /dev/null +++ b/src/uset_bench.cc @@ -0,0 +1,86 @@ +// list_bench runs benchmarks against List implementations. +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +static mt19937 rng; +static random_device devrand; + +// reseed picks a new seed for the RNG using the system random device. +static void +reseed() +{ + rng.seed(devrand()); +} + + +static int +randint(int low, int high) +{ + uniform_int_distribution dist(low, high); + return dist(rng); +} + +static void +benchmark(ods::USet& set, int ops) +{ + for (int i = 0; i < ops; i++) { + auto op = randint(0, 3); + int val = randint(1, 100); + + switch (op) { + // add + case 0: + case 1: + cout << "\tadd " << val << endl; + set.add(val); + break; + // remove + case 2: + set.remove(val); + break; + // find + case 3: + set.find(val); + break; + } + } +} + + +static void +run(string label, ods::USet& list, int ops) +{ + std::chrono::steady_clock clock; + + auto start = clock.now(); + benchmark(list, ops); + auto stop = clock.now(); + + std::chrono::duration delta = stop - start; + cerr << label << " @ " << ops << " ops: " << delta.count() << "s" << endl; +} + + +int +main(int argc, char *argv[]) +{ + int ops = 1000; + + if (argc == 2) { + ops = stoi(argv[1]); + } + + reseed(); + + ods::SimpUSet us; + run("SimpUSet", us, ops); + + return 0; +} \ No newline at end of file