perf性能测试代码实现,但测试代码写起来怪怪的,日志打印的信息也不直观。后续再调整吧

This commit is contained in:
建峰 2026-05-12 23:38:49 +08:00
parent cd6eff28a7
commit c422bc976a
7 changed files with 508 additions and 1 deletions

View File

@ -23,3 +23,4 @@ add_subdirectory(src)
add_subdirectory(demo) add_subdirectory(demo)
add_subdirectory(3rdparty) add_subdirectory(3rdparty)
add_subdirectory(test) add_subdirectory(test)
add_subdirectory(perf)

22
perf/CMakeLists.txt Normal file
View File

@ -0,0 +1,22 @@
# set the name of project
project(perf)
# include
include_directories(.)
# add src
aux_source_directory(. SRCS)
# generate target
add_executable(${PROJECT_NAME} ${SRCS})
# link libary
target_link_libraries(
${PROJECT_NAME}
unicstl
unity
)
# install
install(TARGETS ${PROJECT_NAME} DESTINATION bin)

21
perf/main.c Normal file
View File

@ -0,0 +1,21 @@
/**
* @file main.c
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2026-05-12
*
* @copyright Copyright (c) 2026
*
*/
#include "perf.h"
int main(int argc, char *argv[])
{
PERF_INIT();
perf_deque();
return 0;
}

79
perf/perf.c Normal file
View File

@ -0,0 +1,79 @@
/**
* @file main.c
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2026-05-12
*
* @copyright Copyright (c) 2026
*
*/
#include "perf.h"
#define PERF_FORMAT_HEAD "%-24s %-4s %-6s %-12s\n"
#define PERF_FORMAT_DATA "%-24s T%-3d %-6d %8.3f ms\n"
void perf_init(void)
{
printf(PERF_FORMAT_HEAD, "function", " id ", " loop", " time(ms)");
printf(PERF_FORMAT_HEAD, "--------", "----", "------", "------------");
}
void perf_begin(struct _perf_args* args)
{
timespec_get(&args->start, TIME_UTC);
}
double calc_elapsed(struct timespec start, struct timespec end)
{
return (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
}
void perf_end(struct _perf_args* args)
{
timespec_get(&args->end, TIME_UTC);
args->elapsed = calc_elapsed(args->start, args->end);
printf(PERF_FORMAT_DATA, args->name, args->id, 1, 1000 * args->elapsed);
}
void perf_print(struct _perf_args* args)
{
}
#if 0
void perf_run_avg(perf_func_t perf_func, const char *func_name, size_t count)
{
double time_used = 0;
double time_total = 0;
for(size_t i = 0; i < count; i++)
{
perf_start();
perf_func();
perf_end();
time_used = (time_end.tv_sec - time_start.tv_sec) + (time_end.tv_nsec - time_start.tv_nsec) / 1e9;
time_total += time_used;
}
printf(PERF_FORMAT_DATA, func_name, "AVG", 1, 1000 * time_total/count);
}
void perf_run_loop(perf_func_t perf_func, const char *func_name, size_t loop)
{
double time_used = 0;
perf_start();
for(size_t i = 0; i < loop; i++)
{
perf_func();
}
perf_end();
time_used = (time_end.tv_sec - time_start.tv_sec) + (time_end.tv_nsec - time_start.tv_nsec) / 1e9;
printf(PERF_FORMAT_DATA, func_name, "LOOP", loop, 1000 * time_used);
}
#endif

70
perf/perf.h Normal file
View File

@ -0,0 +1,70 @@
/**
* @file perf.h
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2026-05-12
*
* @copyright Copyright (c) 2026
*
*/
#ifndef _PERF_H_
#define _PERF_H_
#include "unicstl.h"
#include <time.h>
typedef void (*perf_func_t)(void);
struct _perf_args
{
size_t id;
const char *name;
struct timespec start; // [C11]
struct timespec end; // [C11]
double elapsed;
};
/**
* @brief initialize the performance test
*
*/
#define PERF_INIT() perf_init()
/**
* @brief run the performance test function
*
*/
#define RUN_PERF(ID, func) do{\
struct _perf_args args = {\
.id = ID, \
.name = #func, \
.start = {0}, \
.end = {0}, \
.elapsed = 0, \
};\
perf_begin(&args); \
(func); \
perf_end(&args); \
}while(0)
#define RUN_PERF_T1(func) RUN_PERF(1, func)
#define RUN_PERF_T2(func) RUN_PERF(2, func)
#define RUN_PERF_T3(func) RUN_PERF(3, func)
/**
* @brief print the performance test result
*
*/
void perf_init(void);
void perf_begin(struct _perf_args* args);
void perf_end(struct _perf_args* args);
/**
* @brief perf test items
*
*/
void perf_deque(void);
#endif // !_PERF_H_

313
perf/perf_deque.c Normal file
View File

@ -0,0 +1,313 @@
/**
* @file perf_deque.c
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2026-05-12
*
* @copyright Copyright (c) 2026
*
*/
#include "perf.h"
#if 0
static void demo_deque_num(void)
{
size_t i = 0;
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
int temp = 0;
size_t len = sizeof(data) / sizeof(data[0]);
deque_t deque = deque_new(sizeof(int), len);
deque->print_obj = print_num;
printf("\n\n----- demo_deque_num -----\n");
printf("----- after push_back -----\n");
for (i = 0; i < len; i++)
{
deque->push_back(deque, &data[i]);
deque->front(deque, &temp);
printf("front = ");
deque->print_obj(&temp);
deque->back(deque, &temp);
printf("\tback = ");
deque->print_obj(&temp);
printf("\tsize = %2d\n", deque->size(deque));
}
printf("----- print -----\n");
deque->print(deque);
printf("\n");
deque->clear(deque);
if (deque->empty(deque))
{
printf("----- empty -----\n");
}
printf("----- push_back -----\n");
for (i = 0; i < len; i++)
{
deque->push_back(deque, &data[i]);
}
printf("----- after pop_back -----\n");
for (i = 0; i < len + 1; i++)
{
if (true == deque->pop_back(deque, &temp))
{
printf("pop = ");
deque->print_obj(&temp);
if (true == deque->front(deque, &temp))
{
printf("front = ");
deque->print_obj(&temp);
}
if (deque->back(deque, &temp))
{
printf("back = ");
deque->print_obj(&temp);
}
printf("size = %2d\n", deque->size(deque));
}
else
{
printf("pop failed! because it is empty\n");
}
if (deque->empty(deque))
{
printf("----- empty -----\n");
}
}
printf("----- after push_front -----\n");
for (i = 0; i < len; i++)
{
deque->push_front(deque, &data[i]);
deque->front(deque, &temp);
printf("front = ");
deque->print_obj(&temp);
deque->back(deque, &temp);
printf("\tback = ");
deque->print_obj(&temp);
printf("\tsize = %2d\n", deque->size(deque));
}
printf("----- print -----\n");
deque->print(deque);
printf("\n");
deque->clear(deque);
if (deque->empty(deque))
{
printf("----- empty -----\n");
}
printf("----- push_front -----\n");
for (i = 0; i < len; i++)
{
deque->push_front(deque, &data[i]);
}
for (i = 0; i < len + 1; i++)
{
if (true == deque->pop_front(deque, &temp))
{
printf("pop = ");
deque->print_obj(&temp);
if (true == deque->front(deque, &temp))
{
printf("front = ");
deque->print_obj(&temp);
}
if (deque->back(deque, &temp))
{
printf("back = ");
deque->print_obj(&temp);
}
printf("size = %2d\n", deque->size(deque));
}
}
#if 0
printf("----- push_front -----\n");
for (i = 0; i < len; i++)
{
deque->push_front(deque, &data[i]);
}
printf("----- print -----\n");
deque->print(deque);
printf("\n");
printf("----- set -----\n");
temp = 11;
deque->set(deque, 0, &temp);
temp = 22;
deque->set(deque, len/2, &temp);
temp = 33;
deque->set(deque, len - 1, &temp);
printf("----- print -----\n");
deque->print(deque);
printf("\n");
printf("----- get -----\n");
for (i = 0; i < len; i++)
{
if (true == deque->get(deque, i, &temp))
{
printf("deque[%2d] = ", i);
deque->print_obj(&temp);
printf("\n");
}
}
#endif
deque_free(&deque);
}
#endif
#define CAPACITY_T1 1024
#define OBJ_SIZE_T1 256
#define CAPACITY_T2 1024
#define OBJ_SIZE_T2 4096
#define CAPACITY_T3 8192
#define OBJ_SIZE_T3 4096
struct _test_obj
{
void *obj;
size_t obj_size;
size_t capacity;
}test_obj;
static deque_t deque = NULL;
void perf_deque_new(void)
{
deque = deque_new(test_obj.obj_size, test_obj.capacity);
}
void perf_deque_push_back(void)
{
for (size_t i = 0; i < test_obj.capacity; i++)
{
deque->push_back(deque, &test_obj.obj);
}
}
void perf_deque_pop_back(void)
{
for (size_t i = 0; i < test_obj.capacity; i++)
{
deque->pop_back(deque, &test_obj.obj);
}
}
void perf_deque_push_front(void)
{
for (size_t i = 0; i < test_obj.capacity; i++)
{
deque->push_front(deque, &test_obj.obj);
}
}
void perf_deque_pop_front(void)
{
for (size_t i = 0; i < test_obj.capacity; i++)
{
deque->pop_front(deque, &test_obj.obj);
}
}
void perf_deque_free(void)
{
deque_free(&deque);
}
void perf_deque_t1(void)
{
test_obj.capacity = CAPACITY_T1;
test_obj.obj_size = OBJ_SIZE_T1;
test_obj.obj = malloc(test_obj.capacity);
if(test_obj.obj == NULL)
{
printf( __FUNCTION__, "malloc failed");
return;
}
RUN_PERF_T1( perf_deque_new() );
RUN_PERF_T1( perf_deque_push_back() );
RUN_PERF_T1( perf_deque_pop_back() );
RUN_PERF_T1( perf_deque_push_front() );
RUN_PERF_T1( perf_deque_pop_front() );
RUN_PERF_T1( perf_deque_free() );
free(test_obj.obj);
}
void perf_deque_t2(void)
{
test_obj.capacity = CAPACITY_T2;
test_obj.obj_size = OBJ_SIZE_T2;
test_obj.obj = malloc(test_obj.capacity);
if(test_obj.obj == NULL)
{
printf( __FUNCTION__, "malloc failed");
return;
}
RUN_PERF_T2( perf_deque_new() );
RUN_PERF_T2( perf_deque_push_back() );
RUN_PERF_T2( perf_deque_pop_back() );
RUN_PERF_T2( perf_deque_push_front() );
RUN_PERF_T2( perf_deque_pop_front() );
RUN_PERF_T2( perf_deque_free() );
free(test_obj.obj);
}
void perf_deque_t3(void)
{
test_obj.capacity = CAPACITY_T3;
test_obj.obj_size = OBJ_SIZE_T3;
test_obj.obj = malloc(test_obj.capacity);
if(test_obj.obj == NULL)
{
printf( __FUNCTION__, "malloc failed");
return;
}
RUN_PERF_T3( perf_deque_new() );
RUN_PERF_T3( perf_deque_push_back() );
RUN_PERF_T3( perf_deque_pop_back() );
RUN_PERF_T3( perf_deque_push_front() );
RUN_PERF_T3( perf_deque_pop_front() );
RUN_PERF_T3( perf_deque_free() );
free(test_obj.obj);
}
void perf_deque(void)
{
perf_deque_t1();
perf_deque_t2();
perf_deque_t3();
}

View File

@ -1 +1,2 @@
start /b /wait build/release/bin/demo.exe @REM start /b /wait build/release/bin/demo.exe
start /b /wait build/release/bin/perf.exe