random tests

v1
Brett 2023-03-04 22:38:25 -05:00
parent d895e6d033
commit bd89abb2f3
2 changed files with 77 additions and 90 deletions

View File

@ -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

View File

@ -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