|
|
/** |
|
|
* Intensive memory pool test to demonstrate optimization benefits |
|
|
* Updated for new ll_queue API |
|
|
*/ |
|
|
|
|
|
#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(); |
|
|
|
|
|
struct UASYNC* ua = uasync_create(); |
|
|
struct ll_queue* queue = queue_new(ua, 0); // Без пулов |
|
|
|
|
|
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++) { |
|
|
void* data = queue_entry_new(64); |
|
|
queue_data_put(queue, data, i); // Используем ID = i |
|
|
} |
|
|
|
|
|
// Удалить записи (триггер waiters) |
|
|
for (int i = 0; i < 10; i++) { |
|
|
void* retrieved = queue_data_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(); |
|
|
|
|
|
struct UASYNC* ua = uasync_create(); |
|
|
struct ll_queue* queue = queue_new(ua, 0); // С пулами |
|
|
|
|
|
// Создать пул памяти для данных |
|
|
struct memory_pool* pool = memory_pool_init(sizeof(struct ll_entry) + 64); |
|
|
if (!pool) { |
|
|
queue_free(queue); |
|
|
uasync_destroy(ua, 0); |
|
|
return -1.0; |
|
|
} |
|
|
|
|
|
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++) { |
|
|
void* data = queue_entry_new_from_pool(pool); |
|
|
if (data) { |
|
|
queue_data_put(queue, data, i); // Используем ID = i |
|
|
} |
|
|
} |
|
|
|
|
|
// Удалить записи (триггер waiters) |
|
|
for (int i = 0; i < 10; i++) { |
|
|
void* retrieved = queue_data_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); |
|
|
memory_pool_destroy(pool); |
|
|
uasync_destroy(ua, 0); |
|
|
|
|
|
clock_t end = clock(); |
|
|
return ((double)(end - start)) / CLOCKS_PER_SEC; |
|
|
} |
|
|
|
|
|
int main() { |
|
|
printf("=== Интенсивный тест пулов памяти ===\n"); |
|
|
printf("Тестируется производительность с пулами vs без пулов\n\n"); |
|
|
|
|
|
const int iterations = 1000; |
|
|
|
|
|
printf("Запуск теста без пулов памяти...\n"); |
|
|
double time_without = test_without_pools(iterations); |
|
|
printf("Время без пулов: %.3f сек\n", time_without); |
|
|
printf("Waiter callbacks: %d\n\n", waiter_callback_count); |
|
|
|
|
|
waiter_callback_count = 0; |
|
|
|
|
|
printf("Запуск теста с пулами памяти...\n"); |
|
|
double time_with = test_with_pools(iterations); |
|
|
printf("Время с пулами: %.3f сек\n", time_with); |
|
|
printf("Waiter callbacks: %d\n\n", waiter_callback_count); |
|
|
|
|
|
if (time_with > 0 && time_without > 0) { |
|
|
double speedup = time_without / time_with; |
|
|
printf("Результат: пулы памяти дали %.2fx ускорение\n", speedup); |
|
|
if (time_with < time_without) { |
|
|
printf("✅ Пулы памяти эффективны!\n"); |
|
|
} else { |
|
|
printf("⚠️ Пулы памяти не дали преимущества в этом тесте\n"); |
|
|
} |
|
|
} else { |
|
|
printf("❌ Ошибка в тесте с пулами\n"); |
|
|
} |
|
|
|
|
|
return 0; |
|
|
} |