Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Makefile.bench.include
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ bench_bench_pivx_SOURCES = \
bench/crypto_hash.cpp \
bench/perf.cpp \
bench/perf.h \
bench/prevector_destructor.cpp
bench/prevector.cpp

bench_bench_pivx_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) -I$(builddir)/bench/
bench_bench_pivx_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
Expand Down
89 changes: 89 additions & 0 deletions src/bench/prevector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright (c) 2015-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "bench/bench.h"

#include "compat.h"
#include "prevector.h"
#include "serialize.h"
#include "streams.h"

#include <type_traits>

// GCC 4.8 is missing some C++11 type_traits,
// https://www.gnu.org/software/gcc/gcc-5/changes.html
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
#define IS_TRIVIALLY_CONSTRUCTIBLE std::has_trivial_default_constructor
#else
#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivially_default_constructible
#endif

struct nontrivial_t {
int x;
nontrivial_t() :x(-1) {}
};
static_assert(!IS_TRIVIALLY_CONSTRUCTIBLE<nontrivial_t>::value,
"expected nontrivial_t to not be trivially constructible");

typedef unsigned char trivial_t;
static_assert(IS_TRIVIALLY_CONSTRUCTIBLE<trivial_t>::value,
"expected trivial_t to be trivially constructible");

template <typename T>
static void PrevectorDestructor(benchmark::State& state)
{
while (state.KeepRunning()) {
for (auto x = 0; x < 1000; ++x) {
prevector<28, T> t0;
prevector<28, T> t1;
t0.resize(28);
t1.resize(29);
}
}
}

template <typename T>
static void PrevectorClear(benchmark::State& state)
{

while (state.KeepRunning()) {
for (auto x = 0; x < 1000; ++x) {
prevector<28, T> t0;
prevector<28, T> t1;
t0.resize(28);
t0.clear();
t1.resize(29);
t0.clear();
}
}
}

template <typename T>
void PrevectorResize(benchmark::State& state)
{
while (state.KeepRunning()) {
prevector<28, T> t0;
prevector<28, T> t1;
for (auto x = 0; x < 1000; ++x) {
t0.resize(28);
t0.resize(0);
t1.resize(29);
t1.resize(0);
}
}
}

#define PREVECTOR_TEST(name) \
static void Prevector ## name ## Nontrivial(benchmark::State& state) { \
PrevectorResize<nontrivial_t>(state); \
} \
BENCHMARK(Prevector ## name ## Nontrivial); \
static void Prevector ## name ## Trivial(benchmark::State& state) { \
PrevectorResize<trivial_t>(state); \
} \
BENCHMARK(Prevector ## name ## Trivial);

PREVECTOR_TEST(Clear)
PREVECTOR_TEST(Destructor)
PREVECTOR_TEST(Resize)
36 changes: 0 additions & 36 deletions src/bench/prevector_destructor.cpp

This file was deleted.

89 changes: 44 additions & 45 deletions src/prevector.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <stdint.h>
#include <string.h>

#include <algorithm>
#include <cstddef>
#include <iterator>
#include <type_traits>

Expand Down Expand Up @@ -194,16 +196,27 @@ class prevector {
T* item_ptr(difference_type pos) { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }
const T* item_ptr(difference_type pos) const { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }

void fill(T* dst, ptrdiff_t count, const T& value = T{}) {
std::fill_n(dst, count, value);
}

template<typename InputIterator>
void fill(T* dst, InputIterator first, InputIterator last) {
while (first != last) {
new(static_cast<void*>(dst)) T(*first);
++dst;
++first;
}
}

public:
void assign(size_type n, const T& val) {
clear();
if (capacity() < n) {
change_capacity(n);
}
while (size() < n) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T(val);
}
_size += n;
fill(item_ptr(0), n, val);
}

template<typename InputIterator>
Expand All @@ -213,11 +226,8 @@ class prevector {
if (capacity() < n) {
change_capacity(n);
}
while (first != last) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T(*first);
++first;
}
_size += n;
fill(item_ptr(0), first, last);
}

prevector() {}
Expand All @@ -228,31 +238,23 @@ class prevector {

explicit prevector(size_type n, const T& val = T()) {
change_capacity(n);
while (size() < n) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T(val);
}
_size += n;
fill(item_ptr(0), n, val);
}

template<typename InputIterator>
prevector(InputIterator first, InputIterator last) {
size_type n = last - first;
change_capacity(n);
while (first != last) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T(*first);
++first;
}
_size += n;
fill(item_ptr(0), first, last);
}

prevector(const prevector<N, T, Size, Diff>& other) {
change_capacity(other.size());
const_iterator it = other.begin();
while (it != other.end()) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T(*it);
++it;
}
size_type n = other.size();
change_capacity(n);
_size += n;
fill(item_ptr(0), other.begin(), other.end());
}

prevector(prevector<N, T, Size, Diff>&& other) {
Expand All @@ -263,14 +265,7 @@ class prevector {
if (&other == this) {
return *this;
}
resize(0);
change_capacity(other.size());
const_iterator it = other.begin();
while (it != other.end()) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T(*it);
++it;
}
assign(other.begin(), other.end());
return *this;
}

Expand Down Expand Up @@ -314,16 +309,20 @@ class prevector {
}

void resize(size_type new_size) {
if (size() > new_size) {
size_type cur_size = size();
if (cur_size == new_size) {
return;
}
if (cur_size > new_size) {
erase(item_ptr(new_size), end());
return;
}
if (new_size > capacity()) {
change_capacity(new_size);
}
while (size() < new_size) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T();
}
ptrdiff_t increase = new_size - cur_size;
fill(item_ptr(cur_size), increase);
_size += increase;
}

void reserve(size_type new_capacity) {
Expand All @@ -346,10 +345,11 @@ class prevector {
if (capacity() < new_size) {
change_capacity(new_size + (new_size >> 1));
}
memmove(item_ptr(p + 1), item_ptr(p), (size() - p) * sizeof(T));
T* ptr = item_ptr(p);
memmove(ptr + 1, ptr, (size() - p) * sizeof(T));
_size++;
new(static_cast<void*>(item_ptr(p))) T(value);
return iterator(item_ptr(p));
new(static_cast<void*>(ptr)) T(value);
return iterator(ptr);
}

void insert(iterator pos, size_type count, const T& value) {
Expand All @@ -358,11 +358,10 @@ class prevector {
if (capacity() < new_size) {
change_capacity(new_size + (new_size >> 1));
}
memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T));
T* ptr = item_ptr(p);
memmove(ptr + count, ptr, (size() - p) * sizeof(T));
_size += count;
for (size_type i = 0; i < count; i++) {
new(static_cast<void*>(item_ptr(p + i))) T(value);
}
fill(item_ptr(p), count, value);
}

template<typename InputIterator>
Expand Down