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 +=  -fno-elide-constructors -Weffc++
 | 
			
		||||
 | 
			
		||||
bin_PROGRAMS :=		ch01ex01 ch01ex03 ch01ex04 ch01ex05 ch01ex06
 | 
			
		||||
bin_PROGRAMS :=		ch01ex01 ch01ex03 ch01ex04 ch01ex05 ch01ex06 \
 | 
			
		||||
			list_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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ check_simplist(void)
 | 
			
		|||
	sl.add(1, 2);
 | 
			
		||||
	sl.add(2, 3);
 | 
			
		||||
	assert(sl.size() == 3);
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	sl.add(0, 4);
 | 
			
		||||
	sl.add(1, 5);
 | 
			
		||||
	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 {
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
class SimpList : List<T> {
 | 
			
		||||
class SimpList : public List<T> {
 | 
			
		||||
public:
 | 
			
		||||
	SimpList();
 | 
			
		||||
	~SimpList(void);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@
 | 
			
		|||
 | 
			
		||||
namespace ods {
 | 
			
		||||
template<typename T>
 | 
			
		||||
class SimpUSet : USet<T> {
 | 
			
		||||
class SimpUSet : public USet<T> {
 | 
			
		||||
public:
 | 
			
		||||
	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