|
|
/** |
|
|
* Intensive memory pool test to demonstrate optimization benefits |
|
|
*/ |
|
|
|
|
|
#include <stdio.h> |
|
|
#include <stdlib.h> |
|
|
#include <string.h> |
|
|
#include <assert.h> |
|
|
#include <time.h> |
|
|
#include <unistd.h> |
|
|
|
|
|
#include "../lib/ll_queue.h" |
|
|
#include "../lib/memory_pool.h" |
|
|
#include "../lib/u_async.h" |
|
|
#include "../lib/debug_config.h" |
|
|
|
|
|
static int waiter_callback_count = 0; |
|
|
|
|
|
static void intensive_waiter_callback(struct ll_queue* q, void* arg) { |
|
|
(void)q; (void)arg; |
|
|
waiter_callback_count++; |
|
|
} |
|
|
|
|
|
// Тест без пулов памяти |
|
|
static double test_without_pools(int iterations) { |
|
|
clock_t start = clock(); |
|
|
|
|
|
uasync_t* ua = uasync_create(); |
|
|
struct ll_queue* queue = queue_new(ua, NULL); // Без пулов |
|
|
|
|
|
for (int cycle = 0; cycle < iterations; cycle++) { |
|
|
// Создать много waiters |
|
|
struct queue_waiter* waiters[32]; |
|
|
for (int i = 0; i < 32; i++) { |
|
|
waiters[i] = queue_wait_threshold(queue, i, 0, intensive_waiter_callback, NULL); |
|
|
} |
|
|
|
|
|
// Добавить записи |
|
|
for (int i = 0; i < 10; i++) { |
|
|
struct ll_entry* entry = queue_entry_new(64); |
|
|
queue_entry_put(queue, entry); |
|
|
} |
|
|
|
|
|
// Удалить записи (триггер waiters) |
|
|
for (int i = 0; i < 10; i++) { |
|
|
struct ll_entry* retrieved = queue_entry_get(queue); |
|
|
if (retrieved) { |
|
|
queue_entry_free(retrieved); |
|
|
} |
|
|
} |
|
|
|
|
|
// Отменить waiters |
|
|
for (int i = 0; i < 32; i++) { |
|
|
if (waiters[i]) { |
|
|
queue_cancel_wait(queue, waiters[i]); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
queue_free(queue); |
|
|
uasync_destroy(ua, 0); |
|
|
|
|
|
clock_t end = clock(); |
|
|
return ((double)(end - start)) / CLOCKS_PER_SEC; |
|
|
} |
|
|
|
|
|
// Тест с пулами памяти |
|
|
static double test_with_pools(int iterations) { |
|
|
clock_t start = clock(); |
|
|
|
|
|
uasync_t* ua = uasync_create(); |
|
|
struct ll_queue* queue = queue_new(ua, NULL); // С пулами (using memory pool) |
|
|
|
|
|
for (int cycle = 0; cycle < iterations; cycle++) { |
|
|
// Создать много waiters |
|
|
struct queue_waiter* waiters[32]; |
|
|
for (int i = 0; i < 32; i++) { |
|
|
waiters[i] = queue_wait_threshold(queue, i, 0, intensive_waiter_callback, NULL); |
|
|
} |
|
|
|
|
|
// Добавить записи |
|
|
for (int i = 0; i < 10; i++) { |
|
|
struct ll_entry* entry = queue_entry_new(64); |
|
|
queue_entry_put(queue, entry); |
|
|
} |
|
|
|
|
|
// Удалить записи (триггер waiters) |
|
|
for (int i = 0; i < 10; i++) { |
|
|
struct ll_entry* retrieved = queue_entry_get(queue); |
|
|
if (retrieved) { |
|
|
queue_entry_free(retrieved); |
|
|
} |
|
|
} |
|
|
|
|
|
// Отменить waiters |
|
|
for (int i = 0; i < 32; i++) { |
|
|
if (waiters[i]) { |
|
|
queue_cancel_wait(queue, waiters[i]); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
// Получить статистику пула |
|
|
size_t allocations, reuse_count; |
|
|
queue_get_pool_stats(queue, &allocations, &reuse_count); |
|
|
|
|
|
queue_free(queue); |
|
|
uasync_destroy(ua, 0); |
|
|
|
|
|
clock_t end = clock(); |
|
|
|
|
|
printf("Pool statistics: allocations=%zu, reuse_count=%zu\n", allocations, reuse_count); |
|
|
if (allocations > 0) { |
|
|
printf("Pool efficiency: %.1f%%\n", (100.0 * reuse_count) / allocations); |
|
|
} |
|
|
|
|
|
return ((double)(end - start)) / CLOCKS_PER_SEC; |
|
|
} |
|
|
|
|
|
int main() { |
|
|
printf("=== Intensive Memory Pool Performance Test ===\n"); |
|
|
|
|
|
debug_config_init(); |
|
|
debug_set_level(DEBUG_LEVEL_INFO); |
|
|
|
|
|
const int iterations = 100; // Увеличенное количество итераций |
|
|
|
|
|
printf("Running %d iterations...\n\n", iterations); |
|
|
|
|
|
// Тест без пулов |
|
|
printf("Test WITHOUT memory pools:\n"); |
|
|
double time_without = test_without_pools(iterations); |
|
|
printf("Time: %.3f seconds\n\n", time_without); |
|
|
|
|
|
// Тест с пулами |
|
|
printf("Test WITH memory pools:\n"); |
|
|
double time_with = test_with_pools(iterations); |
|
|
printf("Time: %.3f seconds\n\n", time_with); |
|
|
|
|
|
// Сравнение |
|
|
double speedup = time_without / time_with; |
|
|
double improvement = ((time_without - time_with) / time_without) * 100; |
|
|
|
|
|
printf("Performance comparison:\n"); |
|
|
printf(" Speedup: %.2fx\n", speedup); |
|
|
printf(" Improvement: %.1f%%\n", improvement); |
|
|
printf(" Time saved: %.3f seconds\n", time_without - time_with); |
|
|
|
|
|
if (speedup > 1.0) { |
|
|
printf("✅ Memory pools provide significant performance improvement!\n"); |
|
|
} else { |
|
|
printf("⚠️ Memory pools show minimal improvement for this workload\n"); |
|
|
} |
|
|
|
|
|
printf("\n=== Test completed ===\n"); |
|
|
return 0; |
|
|
} |