抛弃GdCpp*.dll/pdb历史重新建库。libhv和Sqlite的dll保留

This commit is contained in:
Zhang Jianjun
2026-02-02 16:09:02 +08:00
parent f148ca49e3
commit 4a2a284ac0
292 changed files with 350450 additions and 0 deletions

229
include/CTic.h Normal file
View File

@@ -0,0 +1,229 @@
#ifndef CTICK2_H
#define CTICK2_H
#include "GdCPP_Exports.h"
#include <stdint.h>
#include <Windows.h>
#include <iostream>
/// @brief 在不同的时间点(电脑开机,程序启动,实例启动等)、精度单位(s, ms, us等下计算时间差。
class GDCPP_API CTic
{
// ------ 静态变量和静态成员函数 ------
public:
/// 初始化获取时钟频率和起始值只需要在App或Dll初始化时调用一次。
static bool Init();
// ------ 静态变量必须调用一次Init()确定 -----
/// init()初始化时检测到的系统高精度定时器的频率
static int64_t Freq; //1Hz
// 以下是由Freq转换出来的不同单位的频率供计算不同单位的延迟时选用。
// 减少一个乘法,目的是减少运算量并防止乘法溢出。
static int64_t Freq_1k; //1kHz用于计算1ms的时间差
static int64_t Freq_10k; //10kHz, 用于计算100us的时间差
static int64_t Freq_100k; //100kHz, 用于计算10us以下的时间差。目前假设时钟是100k的整数倍
// 以下用于将时钟数转换成频率。
static int64_t Freq_M10; //0.1Hz
static int64_t Freq_M100; //0.2Hz
/// 记录Init()时的时间戳,当做启动软件时的时间
static int64_t AppStartTick;
/// 获取高精度时钟原始值,保存到指定变量
static inline void QueryCnt(int64_t& t) { QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&t)); }
/// 返回高精度时钟原始值
static inline int64_t QueryCnt() { int64_t t; QueryCnt(t); return t; }
// 四舍五入除法,适合要求更高精度的场合
//static inline int64_t _div(int64_t t, int64_t f) { return (t + f / 2) / f; };
// 截尾除法,运算量最小
static inline int64_t _div(int64_t t, int64_t f) { return t / f; }
/// 延迟一小段时间。延迟过程中不挂起线程长延迟请用Sleep()挂起线程
static void Delay (uint32_t ms) { int64_t start = QueryCnt(); while (((QueryCnt() - start) / Freq_1k) < int(ms)); }
static void Delay_us(uint32_t us) { int64_t start = QueryCnt(); while (((QueryCnt() - start) * 1000 / Freq_1k) < int(us)); }
/// @brief 由时间差计算频率单位分别为1Hz, 0.1Hz, 0.01Hz。
static inline int64_t cnt2freq(int64_t t) { return _div(Freq, t); }
static inline int64_t cnt2freq_p10(int64_t t) { return _div(Freq_M10, t); }
static inline int64_t cnt2freq_p100(int64_t t) { return _div(Freq_M100, t); }
/// 当前计数器原始值
int64_t Cnt;
/// 默认构造函数,获取当前高精度时钟值。
inline CTic() { QueryCnt(Cnt);}
/// @brief 带参数的构造函数,通常复制另一个时钟的值。
/// @param t 不能是负数
inline CTic(int64_t t) : Cnt(t) { _ASSERT(t >= 0); }
inline CTic(const CTic &s) : Cnt(s.Cnt){ }
/// 更新计数器值并返回原始值
inline int64_t Update() { QueryCnt(Cnt); return Cnt; }
// 时钟数转不同单位的时间
static inline int64_t to_s (int64_t t) { return _div(t, Freq); } // 时钟计数转时间单位为s
static inline int64_t to_ms (int64_t t) { return _div(t, Freq_1k); } // 时钟计数转时间单位为ms
static inline int64_t to_100us(int64_t t) { return _div(t, Freq_10k); } // 时钟计数转时间单位为100us
static inline int64_t to_10us (int64_t t) { return _div(t, Freq_100k);} // 时钟计数转时间单位为10us。测试算法到10us精度足够了
static inline int64_t to_us (int64_t t) { return _div(t*10, Freq_100k);} // 时钟计数转时间单位为us。 这一档开始比前面的运算量多一个乘法
static inline int64_t to_ns (int64_t t) { return _div(t*10000,Freq_100k);} // 时钟计数转时间单位为ns。 注意仅用于短时间的计算t太大乘法会溢出。
static inline int64_t ms2cnt(int64_t t) { return t * Freq_1k; } // 时间转时钟计数单位为ms
static inline int64_t us2cnt(int64_t t) { return _div(t * Freq_100k, 10); } // 时间转时钟计数单位为us
static inline int64_t ns2cnt(int64_t t) { return _div(t * Freq_100k, 10000);; } // 时间转时钟计数单位为ns
inline int64_t to_s() const { return to_s (Cnt); }
inline int64_t to_ms() const { return to_ms (Cnt); } // 普通计算用这一档
inline int64_t to_100us()const { return to_100us (Cnt); }
inline int64_t to_10us() const { return to_10us (Cnt); } // 测试算法到10us精度足够了
inline int64_t to_us() const { return to_us (Cnt); } // 这一档开始会多算一个乘法
inline int64_t to_ns() const { return to_ns (Cnt); } // 注意t不能太大乘法会溢出
// 这些是最常用的函数,获取两次访问之间的时间差,同时更新时间计数。
// 两次访问包括构造函数、Update()、elapse()、sincePowerOn()、sinceAppRun(),以及子类Tick2::sinceStart()
inline int64_t elapse_s() { auto bak = Cnt; QueryCnt(Cnt); return to_s (Cnt - bak); }
inline int64_t elapse() { auto bak = Cnt; QueryCnt(Cnt); return to_ms (Cnt - bak); }
inline int64_t elapse_100us(){ auto bak = Cnt; QueryCnt(Cnt); return to_100us(Cnt - bak); }
inline int64_t elapse_10us() { auto bak = Cnt; QueryCnt(Cnt); return to_10us (Cnt - bak); }
inline int64_t elapse_us() { auto bak = Cnt; QueryCnt(Cnt); return to_us (Cnt - bak); }
inline int64_t elapse_ns() { auto bak = Cnt; QueryCnt(Cnt); return to_ns (Cnt - bak); }
inline int64_t elapse_raw() { auto bak = Cnt; QueryCnt(Cnt); return Cnt - bak; }
/// 获取从电脑开机开始记的计时器值。
static inline int64_t PowerOn_s() { return to_s (QueryCnt()); }
static inline int64_t PowerOn() { return to_ms (QueryCnt()); }
static inline int64_t PowerOn_100us() { return to_100us(QueryCnt()); }
inline int64_t powerOn_s() { QueryCnt(Cnt); return to_s (); }
inline int64_t powerOn() { QueryCnt(Cnt); return to_ms (); }
inline int64_t powerOn_100us() { QueryCnt(Cnt); return to_100us(); }
/// 获取程序启动后执行Init()开始算起的时间。通常在App启动时调用Init(),因此可以等于程序启动后的时间
static inline int64_t AppRun_s() { return to_s (QueryCnt() - AppStartTick); }
static inline int64_t AppRun() { return to_ms (QueryCnt() - AppStartTick); }
static inline int64_t AppRun_100us() { return to_100us(QueryCnt() - AppStartTick); }
inline int64_t appRun_s() { QueryCnt(Cnt); return to_s (Cnt - AppStartTick); }
inline int64_t appRun() { QueryCnt(Cnt); return to_ms (Cnt - AppStartTick); }
inline int64_t appRun_100us() { QueryCnt(Cnt); return to_100us(Cnt - AppStartTick); }
inline int64_t since_s (const CTic& start) { QueryCnt(Cnt); return to_s (Cnt - start.Cnt); }
inline int64_t since (const CTic& start) { QueryCnt(Cnt); return to_ms (Cnt - start.Cnt); }
inline int64_t since_100us (const CTic& start) { QueryCnt(Cnt); return to_100us (Cnt - start.Cnt); }
// 两个实例相减,得到计数值的差值
inline int64_t operator -(const CTic& t) {return Cnt - t.Cnt;}
};
// 计数两个实例的时间差
static inline int64_t DiffTime_s (const CTic& start, const CTic& end) { return CTic::to_s (end.Cnt - start.Cnt); }
static inline int64_t DiffTime (const CTic& start, const CTic& end) { return CTic::to_ms (end.Cnt - start.Cnt); }
static inline int64_t DiffTime_100us(const CTic& start, const CTic& end) { return CTic::to_100us(end.Cnt - start.Cnt); }
static inline int64_t DiffTime_10us (const CTic& start, const CTic& end) { return CTic::to_10us (end.Cnt - start.Cnt); }
static inline int64_t DiffTime_us (const CTic& start, const CTic& end) { return CTic::to_us (end.Cnt - start.Cnt); }
static inline int64_t DiffTime_ns (const CTic& start, const CTic& end) { return CTic::to_ns (end.Cnt - start.Cnt); }
/// @brief 双计时器。应用场景:某个算法包含多个耗时的步骤,需要统计每一步的时间和总时间。
/// @detail 示例:
/// 1. 算法开头构造Tick2实例或Restart()现有实例
/// Tick2 t; //或t.Restart();
///
/// 2. 分步统计耗时
/// Step1(); // 步骤1
/// log(t.elapse()); // 记录步骤1耗时
/// Step2(); // 步骤2
/// log(t.elapse()); // 记录步骤2耗时
/// Step3(); // 步骤3
/// log(t.elapse()); // 记录步骤3耗时
///
/// 2. 统计总耗时
/// log(t.sinceStart());// 记录总耗时
class GDCPP_API CTic2 : public CTic
{
public:
inline CTic2()
: Start(Cnt) // 基类构造时用默认构造函数本类构造Start时用直接复制Cnt值避免再获取一次
{
}
inline CTic2(const CTic2 &s)
: Start(s.Start)
{
Cnt = s.Cnt;
}
/// @brief 保存起始时间
CTic Start;
/// @brief 重置两个定时器的值。
inline void Restart() {QueryCnt(Cnt); Start.Cnt = Cnt;}
/// 用于最近获取过时间,快速重置起始时间,
inline void fastRestart(){Start.Cnt = Cnt; }
/// 从构造实例或重置起经过了多少时间
inline int64_t sinceStart_s() { QueryCnt(Cnt); return to_s (Cnt - Start.Cnt); }
inline int64_t sinceStart() { QueryCnt(Cnt); return to_ms (Cnt - Start.Cnt); }
inline int64_t sinceStart_100us(){ QueryCnt(Cnt); return to_100us(Cnt - Start.Cnt); }
inline int64_t sinceStart_10us() { QueryCnt(Cnt); return to_10us (Cnt - Start.Cnt); }
inline int64_t sinceStart_us() { QueryCnt(Cnt); return to_us (Cnt - Start.Cnt); }
inline int64_t sinceStart_ns() { QueryCnt(Cnt); return to_ns (Cnt - Start.Cnt); }
};
/// @brief 在CTic基础上增加计算N个时间戳的差值的平均
class GDCPP_API CAvgDiffTick
: public CTic
{
public:
CAvgDiffTick(int n = 0)
: N(n)
{
if (n > 0) Buf = new int64_t[n];
}
~CAvgDiffTick()
{
delete[] Buf;
}
void setSize(int n) {
_ASSERT(n != 0);
if (n != N) {
if (Buf) delete[] Buf;
Buf = new int64_t[n];
N = n;
}
clear();
}
/// @brief 添加一个新值,返回差值的平均
int64_t add(int64_t newvalue);
inline int64_t add()
{
return add(Update());
}
void clear()
{
Cnt = 0;
index = 0;
}
int Avg() { return _Avg; }
// 测试代码
static void Test1(int avgnum = 4);
static void Test2(int avgnum = 4);
protected:
int64_t* Buf = nullptr; // 最近N个CTic的缓冲区
int64_t Cnt = 0; // 已经缓冲的计数
int index = 0; // 新增数据的下标
int N; // 平均次数 = 缓冲区长度
int _Avg = 0; // 最近一次的平均值
};
#endif // CTICK_H