random tests
parent
d895e6d033
commit
bd89abb2f3
|
@ -8,21 +8,10 @@
|
||||||
#define BLT_QUEUE_H
|
#define BLT_QUEUE_H
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do no use any queue in this file. They are slower than std::queue.
|
*
|
||||||
*/
|
*/
|
||||||
namespace blt {
|
namespace blt {
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct node {
|
|
||||||
T t;
|
|
||||||
node* next;
|
|
||||||
|
|
||||||
node(const T& t, node* next) {
|
|
||||||
this->t = t;
|
|
||||||
this->next = next;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard array backed first in first out queue
|
* Standard array backed first in first out queue
|
||||||
* @tparam T type stored in the queue
|
* @tparam T type stored in the queue
|
||||||
|
@ -39,20 +28,21 @@ namespace blt {
|
||||||
* and deletes the old array from memory.
|
* and deletes the old array from memory.
|
||||||
* @param newSize new size of the internal array
|
* @param newSize new size of the internal array
|
||||||
*/
|
*/
|
||||||
void expand(int newSize) {
|
void expand() {
|
||||||
auto tempData = new T[newSize];
|
int new_size = m_size * 2;
|
||||||
|
auto tempData = new T[new_size];
|
||||||
for (int i = 0; i < m_insertIndex; i++)
|
for (int i = 0; i < m_insertIndex; i++)
|
||||||
tempData[i] = m_data[i];
|
tempData[i] = m_data[i];
|
||||||
delete[] m_data;
|
delete[] m_data;
|
||||||
m_data = tempData;
|
m_data = tempData;
|
||||||
m_size = newSize;
|
m_size = new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void push(const T& t) {
|
void push(const T& t) {
|
||||||
if (m_insertIndex >= m_size) {
|
if (m_insertIndex >= m_size) {
|
||||||
expand(m_size * 2);
|
expand();
|
||||||
}
|
}
|
||||||
m_data[m_insertIndex++] = t;
|
m_data[m_insertIndex++] = t;
|
||||||
}
|
}
|
||||||
|
@ -66,8 +56,6 @@ namespace blt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop() {
|
void pop() {
|
||||||
// TODO: throw exception when popping would result in a overflow?
|
|
||||||
// I didn't make it an exception here due to not wanting to import the class.
|
|
||||||
if (isEmpty())
|
if (isEmpty())
|
||||||
return;
|
return;
|
||||||
m_insertIndex--;
|
m_insertIndex--;
|
||||||
|
@ -96,29 +84,32 @@ namespace blt {
|
||||||
int m_size = 16;
|
int m_size = 16;
|
||||||
int m_headIndex = 0;
|
int m_headIndex = 0;
|
||||||
int m_insertIndex = 0;
|
int m_insertIndex = 0;
|
||||||
T* m_data = new T[m_size];
|
T* m_data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expands the internal array to the new size, copying over the data and shifting its minimal position to index 0
|
* Expands the internal array to allow for more storage of elements
|
||||||
* and deletes the old array from memory.
|
|
||||||
* @param newSize new size of the internal array
|
|
||||||
*/
|
*/
|
||||||
void expand(int newSize) {
|
void expand() {
|
||||||
auto tempData = new T[newSize];
|
int new_size = m_size * 2;
|
||||||
for (int i = 0; i < m_size - m_headIndex; i++)
|
int removed_size = m_size - m_headIndex;
|
||||||
tempData[i] = m_data[i + m_headIndex];
|
auto tempData = new T[new_size];
|
||||||
|
// only copy data from where we've removed onward
|
||||||
|
for (int i = 0; i < removed_size; i++)
|
||||||
|
tempData[i] = m_data[i + m_headIndex]; // but don't copy data we've pop'd
|
||||||
delete[] m_data;
|
delete[] m_data;
|
||||||
m_insertIndex = m_size - m_headIndex;
|
|
||||||
m_headIndex = 0;
|
m_headIndex = 0;
|
||||||
|
m_insertIndex = removed_size - 1;
|
||||||
m_data = tempData;
|
m_data = tempData;
|
||||||
m_size = newSize;
|
m_size = new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
flat_queue(): m_data(new T[m_size]) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void push(const T& t) {
|
void push(const T& t) {
|
||||||
if (m_insertIndex+1 >= m_size) {
|
if (m_insertIndex+1 >= m_size) {
|
||||||
expand(m_size * 2);
|
expand();
|
||||||
}
|
}
|
||||||
m_data[m_insertIndex++] = t;
|
m_data[m_insertIndex++] = t;
|
||||||
}
|
}
|
||||||
|
@ -132,8 +123,6 @@ namespace blt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop() {
|
void pop() {
|
||||||
// TODO: throw exception when popping would result in a overflow?
|
|
||||||
// I didn't make it an exception here due to not wanting to import the class.
|
|
||||||
if (isEmpty())
|
if (isEmpty())
|
||||||
return;
|
return;
|
||||||
m_headIndex++;
|
m_headIndex++;
|
||||||
|
@ -159,40 +148,6 @@ namespace blt {
|
||||||
delete[](m_data);
|
delete[](m_data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// avoid this. it is very slow.
|
|
||||||
template<typename T>
|
|
||||||
class node_queue {
|
|
||||||
private:
|
|
||||||
node<T>* m_head;
|
|
||||||
public:
|
|
||||||
|
|
||||||
void push(const T& t) {
|
|
||||||
if (m_head == nullptr)
|
|
||||||
m_head = new node<T>(t, nullptr);
|
|
||||||
else
|
|
||||||
m_head = new node<T>(t, m_head);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const T& front() const {
|
|
||||||
return m_head->t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop() {
|
|
||||||
auto nextNode = m_head->next;
|
|
||||||
delete (m_head);
|
|
||||||
m_head = nextNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
~node_queue() {
|
|
||||||
auto next = m_head;
|
|
||||||
while (next != nullptr) {
|
|
||||||
auto nextNode = next->next;
|
|
||||||
delete (next);
|
|
||||||
next = nextNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //BLT_QUEUE_H
|
#endif //BLT_QUEUE_H
|
||||||
|
|
|
@ -14,12 +14,11 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <blt/std/random.h>
|
#include <blt/std/random.h>
|
||||||
|
|
||||||
std::array<int, 100000> values{};
|
std::array<int, 15000> values{};
|
||||||
|
|
||||||
std::queue<int> base_queue{};
|
std::queue<int> base_queue{};
|
||||||
blt::flat_queue<int> blt_flat_queue{};
|
blt::flat_queue<int> blt_flat_queue{};
|
||||||
blt::flat_stack<int> blt_flat_stack{};
|
blt::flat_stack<int> blt_flat_stack{};
|
||||||
blt::node_queue<int> blt_node_queue{};
|
|
||||||
|
|
||||||
static inline void fill_queues(){
|
static inline void fill_queues(){
|
||||||
BLT_START_INTERVAL("Insert", "std::queue");
|
BLT_START_INTERVAL("Insert", "std::queue");
|
||||||
|
@ -36,17 +35,11 @@ static inline void fill_queues(){
|
||||||
for (const auto& value : values)
|
for (const auto& value : values)
|
||||||
blt_flat_stack.push(value);
|
blt_flat_stack.push(value);
|
||||||
BLT_END_INTERVAL("Insert", "blt::flat_stack");
|
BLT_END_INTERVAL("Insert", "blt::flat_stack");
|
||||||
|
|
||||||
BLT_START_INTERVAL("Insert", "blt::node_queue");
|
|
||||||
for (const auto& value : values)
|
|
||||||
blt_node_queue.push(value);
|
|
||||||
BLT_END_INTERVAL("Insert", "blt::node_queue");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void validate(){
|
static inline void validate(){
|
||||||
bool std_valid = true;
|
bool std_valid = true;
|
||||||
bool flat_valid = true;
|
bool flat_valid = true;
|
||||||
bool node_valid = true;
|
|
||||||
bool stack_valid = true;
|
bool stack_valid = true;
|
||||||
BLT_START_INTERVAL("Access", "std::queue");
|
BLT_START_INTERVAL("Access", "std::queue");
|
||||||
for (const auto& value : values) {
|
for (const auto& value : values) {
|
||||||
|
@ -69,37 +62,74 @@ static inline void validate(){
|
||||||
BLT_END_INTERVAL("Access", "blt::flat_queue");
|
BLT_END_INTERVAL("Access", "blt::flat_queue");
|
||||||
|
|
||||||
BLT_START_INTERVAL("Access", "blt::flat_stack");
|
BLT_START_INTERVAL("Access", "blt::flat_stack");
|
||||||
for (const auto& value : values) {
|
for (int i = values.size()-1; i > 0; i--) {
|
||||||
|
const auto& value = values[i];
|
||||||
auto front = blt_flat_stack.top();
|
auto front = blt_flat_stack.top();
|
||||||
|
|
||||||
if (front != value)
|
if (front != value)
|
||||||
stack_valid = false;
|
stack_valid = false;
|
||||||
|
|
||||||
blt_flat_stack.pop();
|
blt_flat_stack.pop();
|
||||||
}
|
}
|
||||||
BLT_END_INTERVAL("Access", "blt::flat_stack");
|
BLT_END_INTERVAL("Access", "blt::flat_stack");
|
||||||
|
|
||||||
BLT_START_INTERVAL("Access", "blt::node_queue");
|
|
||||||
for (const auto& value : values) {
|
|
||||||
auto front = blt_node_queue.front();
|
|
||||||
|
|
||||||
if (front != value)
|
|
||||||
node_valid = false;
|
|
||||||
blt_node_queue.pop();
|
|
||||||
}
|
|
||||||
BLT_END_INTERVAL("Access", "blt::node_queue");
|
|
||||||
|
|
||||||
if (!std_valid)
|
if (!std_valid)
|
||||||
BLT_ERROR("std::queue invalid!");
|
BLT_ERROR("std::queue invalid!");
|
||||||
if (!flat_valid)
|
if (!flat_valid)
|
||||||
BLT_ERROR("blt::flat_queue invalid!");
|
BLT_ERROR("blt::flat_queue invalid!");
|
||||||
if (!node_valid)
|
if (!stack_valid)
|
||||||
BLT_ERROR("blt::node_queue invalid!");
|
BLT_ERROR("blt::stack invalid!");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void random_access() {
|
||||||
|
bool flat_valid = true;
|
||||||
|
bool stack_valid = true;
|
||||||
|
|
||||||
|
BLT_START_INTERVAL("Access", "blt::flat_queue");
|
||||||
|
for (int i = 0; i < 500; i++) {
|
||||||
|
auto front = blt_flat_queue.front();
|
||||||
|
auto next = base_queue.front();
|
||||||
|
|
||||||
|
if (front != next)
|
||||||
|
flat_valid = false;
|
||||||
|
blt_flat_queue.pop();
|
||||||
|
base_queue.pop();
|
||||||
|
}
|
||||||
|
for (int value : values){
|
||||||
|
blt_flat_queue.push(value);
|
||||||
|
base_queue.push(value);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < values.size(); i++) {
|
||||||
|
auto front = blt_flat_queue.front();
|
||||||
|
auto next = base_queue.front();
|
||||||
|
|
||||||
|
if (front != next)
|
||||||
|
flat_valid = false;
|
||||||
|
blt_flat_queue.pop();
|
||||||
|
base_queue.pop();
|
||||||
|
}
|
||||||
|
BLT_END_INTERVAL("Random", "blt::flat_queue");
|
||||||
|
|
||||||
|
BLT_START_INTERVAL("Random", "blt::flat_stack");
|
||||||
|
for (int i = values.size()-1; i > 0; i--) {
|
||||||
|
const auto& value = values[i];
|
||||||
|
auto front = blt_flat_stack.top();
|
||||||
|
|
||||||
|
if (front != value)
|
||||||
|
stack_valid = false;
|
||||||
|
|
||||||
|
blt_flat_stack.pop();
|
||||||
|
}
|
||||||
|
BLT_END_INTERVAL("Random", "blt::flat_stack");
|
||||||
|
|
||||||
|
if (!flat_valid)
|
||||||
|
BLT_ERROR("blt::flat_queue invalid!");
|
||||||
if (!stack_valid)
|
if (!stack_valid)
|
||||||
BLT_ERROR("blt::stack invalid!");
|
BLT_ERROR("blt::stack invalid!");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void test_queues() {
|
static inline void test_queues() {
|
||||||
blt::random<int, std::uniform_int_distribution> rand{1, std::numeric_limits<int>::max()};
|
blt::random<int, std::uniform_int_distribution> rand{1, 100};
|
||||||
|
|
||||||
for (int& value : values){
|
for (int& value : values){
|
||||||
value = rand.get();
|
value = rand.get();
|
||||||
|
@ -107,10 +137,12 @@ static inline void test_queues() {
|
||||||
|
|
||||||
fill_queues();
|
fill_queues();
|
||||||
validate();
|
validate();
|
||||||
|
fill_queues();
|
||||||
|
random_access();
|
||||||
|
|
||||||
BLT_PRINT_PROFILE("Insert", blt::logging::LOG_LEVEL::INFO, true);
|
BLT_PRINT_PROFILE("Insert", blt::logging::LOG_LEVEL::INFO, true);
|
||||||
BLT_PRINT_PROFILE("Access", blt::logging::LOG_LEVEL::INFO, true);
|
BLT_PRINT_PROFILE("Access", blt::logging::LOG_LEVEL::INFO, true);
|
||||||
|
BLT_PRINT_PROFILE("Random", blt::logging::LOG_LEVEL::INFO, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //BLT_TESTS_QUEUE_TESTS_H
|
#endif //BLT_TESTS_QUEUE_TESTS_H
|
||||||
|
|
Loading…
Reference in New Issue