Created
October 4, 2023 08:26
-
-
Save shininglion/aa6b2c1e9468b3572f1d7a541ecce333 to your computer and use it in GitHub Desktop.
branchless v.s. traditional linked list implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
struct Node { | |
void* data; | |
Node* next; | |
}; | |
class List | |
{ | |
public: | |
List() : head(nullptr), tail(nullptr) {} | |
~List() { | |
while (this->head) { | |
auto tmp = this->head; | |
this->head = this->head->next; | |
delete tmp; | |
} | |
} | |
protected: | |
Node* head; | |
Node* tail; | |
}; | |
class BranchlessList : public List | |
{ | |
public: | |
BranchlessList(); | |
void addTail(); | |
}; | |
BranchlessList::BranchlessList() | |
{ | |
constexpr auto offset = sizeof(Node) - sizeof(Node::next); | |
this->tail = reinterpret_cast<Node*>(&(this->head)) - offset; | |
} | |
void BranchlessList::addTail() | |
{ | |
auto node = new Node{nullptr, nullptr}; | |
this->tail->next = node; | |
this->tail = node; | |
} | |
class TraditionList : public List | |
{ | |
public: | |
void addTail(); | |
}; | |
void TraditionList::addTail() | |
{ | |
auto node = new Node{nullptr, nullptr}; | |
if (this->tail) { | |
this->tail->next = node; | |
this->tail = node; | |
} | |
else { | |
this->head = this->tail = node; | |
} | |
} | |
template <typename T, int ELEM_CNT> | |
void perfList() | |
{ | |
T list; | |
for (int i = 0; i < ELEM_CNT; ++i) { | |
list.addTail(); | |
} | |
} | |
int main() | |
{ | |
constexpr auto ELEM_CNT = 100'000'000; | |
perfList<BranchlessList, ELEM_CNT>(); | |
perfList<TraditionList, ELEM_CNT>(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment