39 log_module::write_information(
"\n=== Basic Node Pool Usage Demo ===");
42 node_pool<TestData> pool(2, 512);
45 auto stats = pool.get_statistics();
46 log_module::write_information(
"Initial pool statistics:");
47 log_module::write_information(
" Total chunks: {}", stats.total_chunks);
48 log_module::write_information(
" Total nodes: {}", stats.total_nodes);
49 log_module::write_information(
" Allocated nodes: {}", stats.allocated_nodes);
50 log_module::write_information(
" Free list size: {}", stats.free_list_size);
53 std::vector<TestData*> allocated_nodes;
54 const int NUM_ALLOCATIONS = 100;
56 log_module::write_information(
"\nAllocating {} nodes...", NUM_ALLOCATIONS);
57 for (
int i = 0; i < NUM_ALLOCATIONS; ++i) {
58 auto* node = pool.allocate();
60 node->data = i * 3.14;
61 allocated_nodes.push_back(node);
65 stats = pool.get_statistics();
66 log_module::write_information(
"After allocation:");
67 log_module::write_information(
" Total chunks: {}", stats.total_chunks);
68 log_module::write_information(
" Total nodes: {}", stats.total_nodes);
69 log_module::write_information(
" Allocated nodes: {}", stats.allocated_nodes);
70 log_module::write_information(
" Free list size: {}", stats.free_list_size);
73 log_module::write_information(
"\nVerifying data integrity...");
74 bool integrity_ok =
true;
75 for (
int i = 0; i < NUM_ALLOCATIONS; ++i) {
76 if (allocated_nodes[i]->value != i ||
77 std::abs(allocated_nodes[i]->data - i * 3.14) > 0.001) {
82 log_module::write_information(
"Data integrity: {}", integrity_ok ?
"OK" :
"FAILED");
85 log_module::write_information(
"\nDeallocating half the nodes...");
86 for (
int i = 0; i < NUM_ALLOCATIONS / 2; ++i) {
87 pool.deallocate(allocated_nodes[i]);
88 allocated_nodes[i] =
nullptr;
92 stats = pool.get_statistics();
93 log_module::write_information(
"After partial deallocation:");
94 log_module::write_information(
" Total chunks: {}", stats.total_chunks);
95 log_module::write_information(
" Total nodes: {}", stats.total_nodes);
96 log_module::write_information(
" Allocated nodes: {}", stats.allocated_nodes);
97 log_module::write_information(
" Free list size: {}", stats.free_list_size);
100 for (
int i = NUM_ALLOCATIONS / 2; i < NUM_ALLOCATIONS; ++i) {
101 pool.deallocate(allocated_nodes[i]);
105 stats = pool.get_statistics();
106 log_module::write_information(
"After full deallocation:");
107 log_module::write_information(
" Total chunks: {}", stats.total_chunks);
108 log_module::write_information(
" Total nodes: {}", stats.total_nodes);
109 log_module::write_information(
" Allocated nodes: {}", stats.allocated_nodes);
110 log_module::write_information(
" Free list size: {}", stats.free_list_size);
114 log_module::write_information(
"\n=== Concurrent Usage Demo ===");
116 constexpr int NUM_THREADS = 4;
117 constexpr int OPERATIONS_PER_THREAD = 1000;
118 constexpr int INITIAL_CHUNKS = 2;
119 constexpr int CHUNK_SIZE = 256;
121 node_pool<TestData> pool(INITIAL_CHUNKS, CHUNK_SIZE);
123 std::atomic<int> total_allocations{0};
124 std::atomic<int> total_deallocations{0};
125 std::atomic<int> allocation_failures{0};
127 auto start_time = std::chrono::high_resolution_clock::now();
129 std::vector<std::thread> threads;
130 threads.reserve(NUM_THREADS);
133 for (
int thread_id = 0; thread_id < NUM_THREADS; ++thread_id) {
134 threads.emplace_back([&, thread_id]() {
135 std::random_device rd;
136 std::mt19937 gen(rd());
137 std::uniform_int_distribution<> dis(0, 100);
139 std::vector<TestData*> local_nodes;
140 local_nodes.reserve(OPERATIONS_PER_THREAD / 2);
142 for (
int op = 0; op < OPERATIONS_PER_THREAD; ++op) {
143 if (dis(gen) < 70 || local_nodes.empty()) {
145 auto* node = pool.allocate();
146 node->value = thread_id * 10000 + op;
147 node->data = thread_id + op * 0.001;
148 local_nodes.push_back(node);
149 total_allocations.fetch_add(1, std::memory_order_relaxed);
150 }
catch (
const std::bad_alloc&) {
151 allocation_failures.fetch_add(1, std::memory_order_relaxed);
154 if (!local_nodes.empty()) {
155 auto idx = std::uniform_int_distribution<size_t>(0, local_nodes.size() - 1)(gen);
156 pool.deallocate(local_nodes[idx]);
157 local_nodes.erase(local_nodes.begin() + idx);
158 total_deallocations.fetch_add(1, std::memory_order_relaxed);
164 for (
auto* node : local_nodes) {
166 pool.deallocate(node);
167 total_deallocations.fetch_add(1, std::memory_order_relaxed);
174 for (
auto& thread : threads) {
178 auto end_time = std::chrono::high_resolution_clock::now();
179 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
181 log_module::write_information(
"Concurrent operations completed in {} ms", duration.count());
182 log_module::write_information(
"Total allocations: {}", total_allocations.load());
183 log_module::write_information(
"Total deallocations: {}", total_deallocations.load());
184 log_module::write_information(
"Allocation failures: {}", allocation_failures.load());
187 auto stats = pool.get_statistics();
188 log_module::write_information(
"Final pool statistics:");
189 log_module::write_information(
" Total chunks: {}", stats.total_chunks);
190 log_module::write_information(
" Total nodes: {}", stats.total_nodes);
191 log_module::write_information(
" Allocated nodes: {}", stats.allocated_nodes);
192 log_module::write_information(
" Free list size: {}", stats.free_list_size);
195 int total_ops = total_allocations.load() + total_deallocations.load();
196 double ops_per_second = (double)total_ops / (duration.count() / 1000.0);
197 log_module::write_information(
"Performance: {} ops/second",
static_cast<int>(ops_per_second));
201 log_module::write_information(
"\n=== Performance Comparison Demo ===");
203 constexpr int NUM_OPERATIONS = 100000;
204 constexpr int WARMUP_OPERATIONS = 10000;
207 log_module::write_information(
"Testing node pool performance...");
208 node_pool<TestData> pool(4, 1024);
211 std::vector<TestData*> warmup_nodes;
212 for (
int i = 0; i < WARMUP_OPERATIONS; ++i) {
213 warmup_nodes.push_back(pool.allocate());
215 for (
auto* node : warmup_nodes) {
216 pool.deallocate(node);
219 auto start_time = std::chrono::high_resolution_clock::now();
221 std::vector<TestData*> pool_nodes;
222 pool_nodes.reserve(NUM_OPERATIONS);
225 for (
int i = 0; i < NUM_OPERATIONS; ++i) {
226 pool_nodes.push_back(pool.allocate());
230 for (
auto* node : pool_nodes) {
231 pool.deallocate(node);
234 auto end_time = std::chrono::high_resolution_clock::now();
235 auto pool_duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
238 log_module::write_information(
"Testing standard allocation performance...");
240 start_time = std::chrono::high_resolution_clock::now();
242 std::vector<std::unique_ptr<TestData>> std_nodes;
243 std_nodes.reserve(NUM_OPERATIONS);
246 for (
int i = 0; i < NUM_OPERATIONS; ++i) {
247 std_nodes.push_back(std::make_unique<TestData>());
253 end_time = std::chrono::high_resolution_clock::now();
254 auto std_duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
256 log_module::write_information(
"Results:");
257 log_module::write_information(
" Node pool: {} Ξs", pool_duration.count());
258 log_module::write_information(
" Standard allocation: {} Ξs", std_duration.count());
260 if (std_duration.count() > 0) {
261 double speedup = (double)std_duration.count() / pool_duration.count();
262 log_module::write_information(
" Speedup: {:.2f}x", speedup);
266 double pool_ops_per_sec = (2.0 * NUM_OPERATIONS) / (pool_duration.count() / 1000000.0);
267 double std_ops_per_sec = (2.0 * NUM_OPERATIONS) / (std_duration.count() / 1000000.0);
269 log_module::write_information(
" Node pool ops/sec: {}",
static_cast<int>(pool_ops_per_sec));
270 log_module::write_information(
" Standard ops/sec: {}",
static_cast<int>(std_ops_per_sec));
274 log_module::write_information(
"\n=== Memory Efficiency Demo ===");
277 node_pool<TestData> small_pool(1, 256);
278 node_pool<TestData> medium_pool(2, 512);
279 node_pool<TestData> large_pool(4, 1024);
281 auto show_pool_info = [](
const auto& pool,
const char* name) {
282 auto stats = pool.get_statistics();
283 size_t memory_usage = stats.total_nodes *
sizeof(
TestData);
284 log_module::write_information(
"{}:", name);
285 log_module::write_information(
" Total chunks: {}", stats.total_chunks);
286 log_module::write_information(
" Total nodes: {}", stats.total_nodes);
287 log_module::write_information(
" Memory usage: {} bytes ({:.1f} KB)", memory_usage, memory_usage / 1024.0);
288 log_module::write_information(
" Node size: {} bytes\n",
sizeof(
TestData));
291 show_pool_info(small_pool,
"Small pool (1x256)");
292 show_pool_info(medium_pool,
"Medium pool (2x512)");
293 show_pool_info(large_pool,
"Large pool (4x1024)");
296 log_module::write_information(
"Testing fragmentation scenario...");
297 std::vector<TestData*> nodes;
300 for (
int i = 0; i < 100; ++i) {
301 nodes.push_back(medium_pool.allocate());
305 for (
size_t i = 0; i < nodes.size(); i += 2) {
306 medium_pool.deallocate(nodes[i]);
310 auto stats = medium_pool.get_statistics();
311 log_module::write_information(
"After fragmentation:");
312 log_module::write_information(
" Allocated nodes: {}", stats.allocated_nodes);
313 log_module::write_information(
" Free list size: {}", stats.free_list_size);
316 int reused_count = 0;
317 for (
size_t i = 0; i < nodes.size() && reused_count < 25; i += 2) {
319 nodes[i] = medium_pool.allocate();
324 stats = medium_pool.get_statistics();
325 log_module::write_information(
"After reuse ({} nodes):", reused_count);
326 log_module::write_information(
" Allocated nodes: {}", stats.allocated_nodes);
327 log_module::write_information(
" Free list size: {}", stats.free_list_size);
330 for (
auto* node : nodes) {
332 medium_pool.deallocate(node);