昨晚一直内耗,一个程序写了三天写不出来,主要是耗时太多了,老板一直不满意。想在VScode上跑一下,昨晚一直报错。今天来公司重新搞了一下,
主要工作有:
1,读取当前时间用tscns
2,输出不用cout用fmt::print或者logi输出
3,ns到北京时间转换用fmtlog.h文件中的方式算出来
4,把昨天晚上上传gitee的文件删掉,重新上传
5,写一个100万次的循环,测试输出时间,给出最大最小值,中位数,标准差,统计各个时间阶段的百分比
如何缩短输出时间:
老板要求从获取时间到时间转化到输出时间,所有的时间在几百ns内,但是我只读取时间然后转化就几百ns,打印时间耗费时间更多,和老板沟通过后,老板说先传到git看看,并且封装成函数,输入0,1,2分别给出获取一次时间,转化为北京时间和总共时间,我今天改的代码:
#include <iostream>
#include <chrono>
#include "../fmtlog.h"
#include "../fmtlog-inl.h" // 假设 TSCNS 类定义在 fmtlog-inl.h 中
// 函数根据模式返回不同的时间统计结果
int get_time(int mode) {
// 创建 TSCNS 实例并初始化
fmtlog::TSCNS tscns;
tscns.init();
fmtlogDetailT<> fmtlog;
int64_t tsc = tscns.rdns();
int64_t tsc1 = tscns.rdns();
// 调用 resetDate 获取午夜时间戳
uint64_t midnightNs = fmtlog.midnightNs;
// 测量输出北京时间的耗时
int64_t tsc2 = tscns.rdns();
uint64_t t = (static_cast<uint64_t>(tsc) > midnightNs)
? (static_cast<uint64_t>(tsc) - midnightNs)
: 0;
uint64_t nanoseconds = t % 1000000000;
t /= 1000000000;
uint64_t seconds = t % 60;
t /= 60;
uint64_t minutes = t % 60;
t /= 60;
uint32_t hours = t;
if (hours > 23) {
hours %= 24;
fmtlog.resetDate();
}
int64_t tsc3 = tscns.rdns();
// 输出格式化的北京时间
fmt::print("Beijing Time: {:02}{:02}{:02}{:09} ns\n", hours, minutes, seconds, nanoseconds);
int64_t tsc4 = tscns.rdns();
// 计算获取时间和格式化所用的时间
int64_t duration_get_ns = tsc1 - tsc;
int64_t duration_format_ns = tsc3 - tsc2;
int64_t duration_print_ns = tsc4 - tsc3;
// 根据模式返回不同的结果
if (mode == 0) {
fmt::print("Time taken to retrieve time: {} ns\n", duration_get_ns);
return int(duration_get_ns);
} else if (mode == 1) {
fmt::print("Time taken to format and output Beijing time: {} ns\n", duration_format_ns);
return int(duration_format_ns);
} else if (mode == 2) {
int total_time = int(duration_print_ns+duration_format_ns);
fmt::print("Total time: {} ns\n", total_time);
return total_time;
} else {
fmt::print("Invalid mode. Please enter 0, 1, or 2.\n");
return -1;
}
}
int main() {
int mode;
std::cout << "Enter mode (0: Retrieve time, 1: Format time, 2: Total time): ";
std::cin >> mode;
int result = get_time(mode);
if (result != -1) {
fmt::print("Result: {} ns\n", result);
}
return 0;
}
1,用TSCNS获取时间比直接用std::chrono::high_resolution_clock::now()快
我直接用了
int64_t timestamp_ns = tn.rdns();
2,用logi输出和用fmt::print
按道理logi比fmt::print快,但是fmtlog的logi有初始定义所以,我修改了logi的宏定义,但其实我觉得两中print方法差不多,都很慢,量级在几万ns,老板说我最早的时候用的
std::setw(2) << std::setfill('0')会更慢
用release跑比用 debug模式跑会快(这个我之前也了解过,但是Clion怎么设置release模式不太会,我自己设置了一下,但是不知道对不对,后面服务器满了我想着删掉点东西,结果误删了cmake-Debug,文件后面跑一直报错,然后我重新github上下载了一下-_-!)
如何写测试文件:
老板让我多测试测试,我昨天只设置了100次循环,他说太少了,所以我设置了100万次循环:
代码:
/*
* 测试文件获取当前时间,并转化为北京时间的时间分布,以及获取一次时间并加上转化时间的时间间隔
* 计算最大时间,最小时间,标准差,中位数,将时间按0-50,50-100,100-150,150-200分类
* 测试次数100万次
* */
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <numeric>
#include "../fmtlog.h"
#include "../fmtlog-inl.h" // 假设 TSCNS 类定义在 fmtlog-inl.h 中
int main() {
// 创建 TSCNS 实例并初始化
fmtlog::TSCNS tscns;
tscns.init();
fmtlogDetailT<> fmtlog;
const int num_iterations = 1000000;
// 存储每次获取时间和格式化时间的耗时
std::vector<int64_t> retrieve_times;
std::vector<int64_t> format_times;
std::vector<int64_t> all_times;
// 存储分布统计
std::vector<int> retrieve_time_buckets(5, 0);
std::vector<int> format_time_buckets(5, 0);
std::vector<int> all_time_buckets(5, 0);
for (int i = 0; i < num_iterations; ++i) {
// 测量获取时间的耗时
int64_t tsc_start_get = tscns.rdns();
int64_t tsc_end_get = tscns.rdns();
int64_t duration_get_ns = tsc_end_get - tsc_start_get;
retrieve_times.push_back(duration_get_ns);
// 统计获取时间的分布
if (duration_get_ns <= 50) retrieve_time_buckets[0]++;
else if (duration_get_ns <= 100) retrieve_time_buckets[1]++;
else if (duration_get_ns <= 150) retrieve_time_buckets[2]++;
else if (duration_get_ns <= 200) retrieve_time_buckets[3]++;
else retrieve_time_buckets[4]++;
// 测量格式化北京时间的耗时
int64_t tsc_start_format = tscns.rdns();
uint64_t tsc = tscns.rdns();
uint64_t t = (static_cast<uint64_t>(tsc) > fmtlog.midnightNs)
? (static_cast<uint64_t>(tsc) - fmtlog.midnightNs)
: 0;
uint64_t nanoseconds = t % 1000000000;
t /= 1000000000;
uint64_t seconds = t % 60;
t /= 60;
uint64_t minutes = t % 60;
t /= 60;
uint32_t hours = t;
if (hours > 23) {
hours %= 24;
fmtlog.resetDate();
}
int64_t tsc_end_format = tscns.rdns();
int64_t duration_format_ns = tsc_end_format - tsc_start_format;
format_times.push_back(duration_format_ns);
// 统计格式化时间的分布
if (duration_format_ns <= 50) format_time_buckets[0]++;
else if (duration_format_ns <= 100) format_time_buckets[1]++;
else if (duration_format_ns <= 150) format_time_buckets[2]++;
else if (duration_format_ns <= 200) format_time_buckets[3]++;
else format_time_buckets[4]++;
// 统计总时间
int64_t all_time = duration_get_ns + duration_format_ns;
all_times.push_back(all_time);
if (all_time <= 50) all_time_buckets[0]++;
else if (all_time <= 100) all_time_buckets[1]++;
else if (all_time <= 150) all_time_buckets[2]++;
else if (all_time <= 200) all_time_buckets[3]++;
else all_time_buckets[4]++;
}
// 计算统计数据
auto calculate_stats = [](const std::vector<int64_t>& times) {
int64_t min_time = *std::min_element(times.begin(), times.end());
int64_t max_time = *std::max_element(times.begin(), times.end());
double mean = std::accumulate(times.begin(), times.end(), 0.0) / times.size();
double sq_sum = std::inner_product(times.begin(), times.end(), times.begin(), 0.0,
std::plus<>(), [mean](double x, double y) { return (x - mean) * (y - mean); });
double std_dev = std::sqrt(sq_sum / times.size());
std::vector<int64_t> sorted_times = times;
std::sort(sorted_times.begin(), sorted_times.end());
int64_t median = sorted_times[times.size() / 2];
return std::make_tuple(min_time, max_time, mean, std_dev, median);
};
// 输出统计数据
auto [retrieve_min, retrieve_max, retrieve_mean, retrieve_std_dev, retrieve_median] = calculate_stats(retrieve_times);
auto [format_min, format_max, format_mean, format_std_dev, format_median] = calculate_stats(format_times);
auto [all_min, all_max, all_mean, all_std_dev, all_median] = calculate_stats(all_times);
fmt::print("Retrieve Time Stats:\n");
fmt::print("Min: {} ns, Max: {} ns, Mean: {:.2f} ns, Std Dev: {:.2f} ns, Median: {} ns\n",
retrieve_min, retrieve_max, retrieve_mean, retrieve_std_dev, retrieve_median);
fmt::print("\nFormat Time Stats:\n");
fmt::print("Min: {} ns, Max: {} ns, Mean: {:.2f} ns, Std Dev: {:.2f} ns, Median: {} ns\n",
format_min, format_max, format_mean, format_std_dev, format_median);
fmt::print("\nAll Time Stats:\n");
fmt::print("Min: {} ns, Max: {} ns, Mean: {:.2f} ns, Std Dev: {:.2f} ns, Median: {} ns\n",
all_min, all_max, all_mean, all_std_dev, all_median);
// 计算分布百分比
auto calculate_percentage = [&](const std::vector<int>& buckets) {
std::vector<double> percentages(buckets.size());
for (size_t i = 0; i < buckets.size(); ++i) {
percentages[i] = static_cast<double>(buckets[i]) / num_iterations * 100.0;
}
return percentages;
};
auto retrieve_percentages = calculate_percentage(retrieve_time_buckets);
auto format_percentages = calculate_percentage(format_time_buckets);
auto all_percentages = calculate_percentage(all_time_buckets);
fmt::print("\nRetrieve Time Distribution (Count and %):\n");
for (size_t i = 0; i < retrieve_percentages.size(); ++i) {
fmt::print("Bucket {}: Count = {}, Percentage = {:.2f}%\n", i, retrieve_time_buckets[i], retrieve_percentages[i]);
}
fmt::print("\nFormat Time Distribution (Count and %):\n");
for (size_t i = 0; i < format_percentages.size(); ++i) {
fmt::print("Bucket {}: Count = {}, Percentage = {:.2f}%\n", i, format_time_buckets[i], format_percentages[i]);
}
fmt::print("\nAll Time Distribution (Count and %):\n");
for (size_t i = 0; i < all_percentages.size(); ++i) {
fmt::print("Bucket {}: Count = {}, Percentage = {:.2f}%\n", i, all_time_buckets[i], all_percentages[i]);
}
return 0;
}
结果:
为什么最短时间和最长时间相差很多:
老板说是因为没有绑核,所以输出不稳定,然后给了我一个绑核的代码:
cpu_set_t cpu_mask;
CPU_ZERO(&cpu_mask);
CPU_SET(mp_tdMgr->m_queryCpuCore, &cpu_mask);
// 设置对应的线程核心
int ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu_mask);
if (ret != 0) {
loge("[PsiSubTrader] Trader Run Worker thread affinity failed! ret:{}", ret);
} else {
logi("[PsiSubTrader] Trader Run Worker thread affinity success! cpu core:{}", mp_tdMgr->m_queryCpuCore);
}
如何删除gitee提交的文件
昨天晚上提交的文件fmtlog里面有.git文件,这样的话会导致gitee仓库那边打不开提交的文件,先删除远程仓库里的错误文件:
两种方法:
1,右键单击文件然后弹出选项选择删除
2,本地操作 ,利用git,cd进库文件夹——>dir会显示当前文件夹下的文件——>git rm -r --cached 待删除的文件名如:git rm -r --cached fmtlog——>git commit -m "删除了文件fmtlog"——>git push
要注意,提交到仓库的文件里面不能有.git(我提交的文件fmtlog和fmt里面都有.git,所以往gitee仓库里面提交了好多次-_-!)