Advertisement
Guest User

Untitled

a guest
Feb 28th, 2015
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.11 KB | None | 0 0
  1. #include <iostream>
  2. #include <list>
  3. #include <vector>
  4.  
  5. template <size_t ChunkSize>
  6. class TFixedAllocator {
  7. union TNode { // union
  8. char data[ChunkSize];
  9. TNode *next; // free chunks of memory form a stack; pointer to the next (or nullptr)
  10. };
  11.  
  12. TNode *free; // the topmost free chunk of memory (or nullptr)
  13. std::vector<TNode*> pools; // all allocated pools of memory
  14. int size = 1; // size of the last allocated pool of memory
  15. const int MAX_SIZE = 1024;
  16.  
  17. void new_pool() { // allocate new pool of memory
  18. if (size < MAX_SIZE) {
  19. size *= 2;
  20. }
  21. free = new TNode[size];
  22.  
  23. // form a stack of chunks of this pool
  24. pools.push_back(free);
  25. for (int i = 0; i < size; ++i) {
  26. free[i].next = &free[i+1];
  27. }
  28. free[size-1].next = nullptr;
  29. }
  30. TFixedAllocator() { // private for singleton
  31. new_pool();
  32. }
  33. public:
  34. TFixedAllocator(const TFixedAllocator&) = delete; // for singleton
  35. static TFixedAllocator& instance () { // singleton
  36. static TFixedAllocator instance;
  37. return instance;
  38. }
  39. void* allocate() {
  40. if (!free) {
  41. new_pool();
  42. }
  43. TNode* result = free; // allocate the topmost element (saved in free)
  44. free = free->next; // and pop it from the stack of free chunks
  45. return static_cast<void*>(result);
  46. }
  47. void deallocate(void* elem) {
  48. TNode* node = static_cast<TNode*>(elem);
  49.  
  50. // add to the stack of chunks
  51. node->next = free;
  52. free = node;
  53. }
  54. ~TFixedAllocator() {
  55. for (auto ptr : pools) {
  56. delete ptr;
  57. }
  58. }
  59. };
  60.  
  61. template <class T>
  62. class TFSBAllocator {
  63. public:
  64. using value_type = T;
  65. using pointer = T*;
  66. using const_pointer = const T*;
  67. using reference = T&;
  68. using const_reference = const T&;
  69. template <class U>
  70. class rebind {
  71. public:
  72. using other = TFSBAllocator<U>;
  73. };
  74.  
  75. pointer allocate(size_t n) {
  76. if (n == 1) {
  77. return static_cast<T*>(TFixedAllocator<sizeof(T)>::instance().allocate());
  78. } else {
  79. return std::allocator<T>().allocate(n);
  80. }
  81. }
  82. void deallocate(pointer p, size_t n) {
  83. if (n == 1) {
  84. TFixedAllocator<sizeof(T)>::instance().deallocate(static_cast<void*>(p));
  85. } else {
  86. return std::allocator<T>().deallocate(p, n);
  87. }
  88. }
  89. void construct(pointer p, const_reference t) {
  90. new (p) T(t);
  91. }
  92. void destroy(pointer p) {
  93. p->~T();
  94. }
  95. };
  96.  
  97. #include <chrono>
  98. using namespace std::chrono;
  99.  
  100. template <class List>
  101. void test(std::string comment, List l) {
  102. std::cout << comment;
  103. auto start_time = high_resolution_clock::now();
  104. for (int i = 0; i < 1e7; ++i) {
  105. l.push_back(i);
  106. }
  107. auto end_time = high_resolution_clock::now();
  108. std::cout << duration_cast<milliseconds>(end_time - start_time).count() << "ms" << std::endl;
  109. }
  110.  
  111. int main() {
  112. test("std::allocator: ", std::list<int>()); // std::allocator: 1816ms
  113. test(" TFSBAllocator: ", std::list<int, TFSBAllocator<int>>()); // TFSBAllocator: 204ms
  114. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement