C/C++ 编程小工具

发布于:2024-10-09 ⋅ 阅读:(6) ⋅ 点赞:(0)

编写了 tools.htools.cpp,用于 Debug、性能测试、打印日志。

tools.h

#ifndef TOOLS_H
#define TOOLS_H

#include <time.h>
#include <fstream>
#include <iostream>
#include <random>
#include <chrono>
#include <vector>
#include <algorithm>

using namespace std;

// 换行
#define pn puts("")

// 代码位置
#define where printf("File: %s, Line: %d, Function: %s. ", __FILE__, __LINE__, __FUNCTION__)

// 打印错误
#define ErrorInfo(format, ...)         \
    {                                  \
        printf("[Error] ");            \
        where;                         \
        printf(format, ##__VA_ARGS__); \
        pn;                            \
    }

// 捕获异常
#define Try(code)                                                  \
    try                                                            \
    {                                                              \
        code;                                                      \
    }                                                              \
    catch (const std::exception &e)                                \
    {                                                              \
        std::cerr << "Catch exception: " << e.what() << std::endl; \
        where;                                                     \
        return -1;                                                 \
    }

// 日志文件
#define LOGFILE "Log.txt"

// 写日志
#define Log(str) PrintLog(str, __FILE__, __LINE__, __FUNCTION__);

/**
 * @brief 打印日志文件
 */
void PrintLog(char *str, const char *FILE, const int LINE, const char *FUNCTION);

// #######################################################################################################

extern std::chrono::steady_clock::time_point TM_start, TM_end; // 记录时钟周期
extern std::vector<int64_t> TM_mem;                            // 存储循环测试结果

#define To_ns(dur) std::chrono::duration_cast<std::chrono::nanoseconds>(dur).count()  // clock -> ns
#define To_us(dur) std::chrono::duration_cast<std::chrono::microseconds>(dur).count() // clock -> us
#define To_ms(dur) std::chrono::duration_cast<std::chrono::milliseconds>(dur).count() // clock -> ms

// 计时器
#define Timer(str, code)                         \
    TM_start = std::chrono::steady_clock::now(); \
    code;                                        \
    TM_end = std::chrono::steady_clock::now();   \
    printf("Running Time of <%s>:\t%15.6f ms\n", \
           str, double(To_ns(TM_end - TM_start)) / 1000000);

// 循环测试
#define Loop(loop, str, code)                        \
    TM_mem.resize(loop, 0);                          \
    for (int __i = 0; __i < loop; __i++)             \
    {                                                \
        TM_start = std::chrono::steady_clock::now(); \
        {                                            \
            code;                                    \
        }                                            \
        TM_end = std::chrono::steady_clock::now();   \
        TM_mem[__i] = To_ns(TM_end - TM_start);      \
    }                                                \
    Analyis_TM(loop, str);

void Analyis_TM(int loop, const char *str); // 分析代码性能

// #######################################################################################################

/**
 * @brief 自定义分配器,确保内存块是 32 字节对齐的
 */
template <typename T>
class AlignedAllocator
{
public:
    using value_type = T;
    using pointer = T *;
    using const_pointer = const T *;
    using reference = T &;
    using const_reference = const T &;
    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;

    template <typename U>
    struct rebind
    {
        using other = AlignedAllocator<U>;
    };

    pointer allocate(size_type n)
    {
        return static_cast<pointer>(std::aligned_alloc(32, n * sizeof(T)));
    }

    void deallocate(pointer p, size_type) noexcept
    {
        std::free(p);
    }
};

/**
 * @brief 具有 32-Btyes 对齐的内存
 */
typedef vector<int32_t, AlignedAllocator<int32_t>> AlignedVcetor;

#endif // TOOLS_H

tools.cpp

#include "tools.h"

void PrintLog(char *str, const char *FILE, const int LINE, const char *FUNCTION)
{
    fstream fout;
    fout.open(LOGFILE, ios::out | ios::app); // 追加

    if (fout.is_open())
    {
        time_t timep;
        time(&timep);            // 获取从1970至今过了多少秒
        string t(ctime(&timep)); // 秒数转化成字符串格式,格式:Tue Oct  8 16:15:42 2024

        fout << t; // 记录时间
        fout << "File: " << FILE << ", Line: " << LINE
             << ", Function: " << FUNCTION << ". "; // 记录位置

        fout << str << endl; // 记录日志信息
        fout.flush();        // 立即写
        fout.close();
    }
    else
    {
        ErrorInfo("Failed to open the file %s.", LOGFILE);
    }
}

//########################################################################################################

std::chrono::steady_clock::time_point TM_start{}, TM_end{};
std::vector<int64_t> TM_mem{};

void Analyis_TM(int loop, const char *str)
{
    int64_t min, max, med, aver = 0;

    auto lt = [](int64_t a, int64_t b)
    { return (a < b); };

    std::sort(TM_mem.data(), TM_mem.data() + loop, lt);

    min = TM_mem[0];
    max = TM_mem[loop - 1];
    med = TM_mem[loop >> 1];
    for (int i = 0; i < loop; i++)
    {
        aver += TM_mem[i];
    }
    aver /= loop;

    printf("Running Time of <%s>:\n\tLoop\t%10d times\n"
           "\tMinimum\t%15.6f ms\n"
           "\tMaximum\t%15.6f ms\n"
           "\tMedian\t%15.6f ms\n"
           "\tAverage\t%15.6f ms\n",
           str, loop,
           double(min) / 1000000, double(max) / 1000000,
           double(med) / 1000000, double(aver) / 1000000);
}


网站公告

今日签到

点亮在社区的每一天
去签到