Add List benchmark.
This commit is contained in:
parent
89ea1fadf2
commit
8eb4ec4274
|
@ -3,9 +3,11 @@ AM_CPPFLAGS += -Wwrite-strings -Wmissing-declarations -Wno-long-long -Werror
|
||||||
AM_CPPFLAGS += -Wunused-variable -std=c++17 -D_XOPEN_SOURCE -O0 -g -I.
|
AM_CPPFLAGS += -Wunused-variable -std=c++17 -D_XOPEN_SOURCE -O0 -g -I.
|
||||||
AM_CPPFLAGS += -fno-elide-constructors -Weffc++
|
AM_CPPFLAGS += -fno-elide-constructors -Weffc++
|
||||||
|
|
||||||
bin_PROGRAMS := ch01ex01 ch01ex03 ch01ex04 ch01ex05 ch01ex06
|
bin_PROGRAMS := ch01ex01 ch01ex03 ch01ex04 ch01ex05 ch01ex06 \
|
||||||
|
list_bench
|
||||||
ch01ex01_SOURCES := ch01ex01.cc
|
ch01ex01_SOURCES := ch01ex01.cc
|
||||||
ch01ex03_SOURCES := ch01ex03.cc
|
ch01ex03_SOURCES := ch01ex03.cc
|
||||||
ch01ex04_SOURCES := ch01ex04.cc
|
ch01ex04_SOURCES := ch01ex04.cc
|
||||||
ch01ex05_SOURCES := ch01ex05.cc
|
ch01ex05_SOURCES := ch01ex05.cc
|
||||||
ch01ex06_SOURCES := ch01ex06.cc
|
ch01ex06_SOURCES := ch01ex06.cc
|
||||||
|
list_bench_SOURCES := list_bench.cc
|
||||||
|
|
|
@ -14,7 +14,7 @@ check_simplist(void)
|
||||||
sl.add(1, 2);
|
sl.add(1, 2);
|
||||||
sl.add(2, 3);
|
sl.add(2, 3);
|
||||||
assert(sl.size() == 3);
|
assert(sl.size() == 3);
|
||||||
|
|
||||||
sl.add(0, 4);
|
sl.add(0, 4);
|
||||||
sl.add(1, 5);
|
sl.add(1, 5);
|
||||||
sl.add(2, 6);
|
sl.add(2, 6);
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
// list_bench runs benchmarks against List implementations.
|
||||||
|
#include <cassert>
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <random>
|
||||||
|
#include <string>
|
||||||
|
#include <ods/list.h>
|
||||||
|
#include <ods/simplist.h>
|
||||||
|
#include <ods/vlist.h>
|
||||||
|
|
||||||
|
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<int> dist(low, high);
|
||||||
|
return dist(rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
randsizet(size_t low, size_t high)
|
||||||
|
{
|
||||||
|
uniform_int_distribution<size_t> dist(low, high);
|
||||||
|
return dist(rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
benchmark(ods::List<int>& list, int ops)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ops; i++) {
|
||||||
|
auto op = randint(0, 3);
|
||||||
|
size_t j = 0;
|
||||||
|
int newval, oldval;
|
||||||
|
|
||||||
|
if (list.size() > 0) {
|
||||||
|
j = randsizet(0, list.size()-1);
|
||||||
|
}
|
||||||
|
switch (op) {
|
||||||
|
// get
|
||||||
|
case 0:
|
||||||
|
if (list.size() == 0) {
|
||||||
|
i--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "\tget " << j << endl;
|
||||||
|
assert(list.get(j) != -1);
|
||||||
|
// set
|
||||||
|
case 1:
|
||||||
|
if (list.size() == 0) {
|
||||||
|
i--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
oldval = list.get(j);
|
||||||
|
newval = oldval;
|
||||||
|
while (newval == oldval) {
|
||||||
|
newval = randint(1, 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "\tset " << j << " from " << oldval << " to " << newval << endl;
|
||||||
|
assert(list.set(j, newval) == oldval);
|
||||||
|
assert(list.get(j) == newval);
|
||||||
|
break;
|
||||||
|
// add
|
||||||
|
case 2:
|
||||||
|
newval = randint(1, 1000000);
|
||||||
|
list.add(j, newval);
|
||||||
|
cout << "\tadd " << j << " " << newval << endl;
|
||||||
|
assert(list.get(j) == newval);
|
||||||
|
break;
|
||||||
|
// remove
|
||||||
|
case 3:
|
||||||
|
if (list.size() == 0) {
|
||||||
|
i--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto old_size = list.size();
|
||||||
|
cout << "\tremove " << j << endl;
|
||||||
|
list.remove(j);
|
||||||
|
assert(list.size() == (old_size-1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
run(string label, ods::List<int>& list, int ops)
|
||||||
|
{
|
||||||
|
std::chrono::steady_clock clock;
|
||||||
|
|
||||||
|
auto start = clock.now();
|
||||||
|
benchmark(list, ops);
|
||||||
|
auto stop = clock.now();
|
||||||
|
|
||||||
|
std::chrono::duration<double> 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::SimpList<int> sl;
|
||||||
|
run("SimpList", sl, ops);
|
||||||
|
|
||||||
|
ods::VList<int> vl;
|
||||||
|
run("VList", vl, ops);
|
||||||
|
}
|
|
@ -9,7 +9,7 @@
|
||||||
namespace ods {
|
namespace ods {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class SimpList : List<T> {
|
class SimpList : public List<T> {
|
||||||
public:
|
public:
|
||||||
SimpList();
|
SimpList();
|
||||||
~SimpList(void);
|
~SimpList(void);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
namespace ods {
|
namespace ods {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class SimpUSet : USet<T> {
|
class SimpUSet : public USet<T> {
|
||||||
public:
|
public:
|
||||||
SimpUSet(void);
|
SimpUSet(void);
|
||||||
~SimpUSet(void);
|
~SimpUSet(void);
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
#ifndef __ODS_ODS_VLIST__
|
||||||
|
#define __ODS_ODS_VLIST__
|
||||||
|
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
#include <ods/list.h>
|
||||||
|
|
||||||
|
namespace ods {
|
||||||
|
|
||||||
|
// VList implements a vector-based list interface.
|
||||||
|
template<typename T>
|
||||||
|
class VList : public List<T> {
|
||||||
|
public:
|
||||||
|
~VList(void);
|
||||||
|
std::size_t size(void);
|
||||||
|
T get(std::size_t);
|
||||||
|
T set(std::size_t, T);
|
||||||
|
void add(std::size_t, T);
|
||||||
|
T remove(std::size_t);
|
||||||
|
private:
|
||||||
|
std::vector<T> vec;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
VList<T>::~VList()
|
||||||
|
{
|
||||||
|
this->vec.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::size_t
|
||||||
|
VList<T>::size()
|
||||||
|
{
|
||||||
|
return this->vec.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T
|
||||||
|
VList<T>::get(std::size_t i)
|
||||||
|
{
|
||||||
|
return this->vec.at(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T
|
||||||
|
VList<T>::set(size_t i, T value)
|
||||||
|
{
|
||||||
|
auto p = this->vec.begin() + i;
|
||||||
|
T old = this->vec.at(i);
|
||||||
|
this->vec.erase(p);
|
||||||
|
this->vec.insert(p, value);
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void
|
||||||
|
VList<T>::add(std::size_t i, T value)
|
||||||
|
{
|
||||||
|
auto p = this->vec.begin() + i;
|
||||||
|
this->vec.insert(p, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T
|
||||||
|
VList<T>::remove(std::size_t i)
|
||||||
|
{
|
||||||
|
auto removed = this->vec.at(i);
|
||||||
|
auto p = this->vec.begin() + i;
|
||||||
|
this->vec.erase(p);
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ods
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __ODS_ODS_VLIST__
|
Loading…
Reference in New Issue