标准委员会动态/ide/编译器信息放在这里
编译器信息最新动态推荐关注hellogcc公众号 本周更新2024-10-30 第278期
https://devblogs.microsoft.com/oldnewthing/20241028-00/?p=110428
emplace_hit 在有序map有很大作用,但是在无序容器,由于不允许重复,hint基本没啥用
但无序容器存在允许重复值的 multixx,这种场景可以用,一般来说用不着
总结了一个表格
实现 | unordered_multixx | unordered_xx |
---|---|---|
是否允许重复 | 是 | 否 |
msvc/STL | 如果匹配就是用 | 如果匹配就使用 |
clang/libcxx | 忽略 | 如果匹配就使用 |
gcc/libstdc++ (large or fast) | 忽略 | 如果匹配就使用 |
gcc/libstdc++ (small and slow) | 忽略 | 使用 |
libstdc++针对不同key的hash有快慢识别,默认是快的 (long double慢) 这里有坑不知道大家记得不
群友mapleFU投稿
之前用 hint 优化过一些有序容器相关的处理( io range 维护什么的),感觉还是挺有用的
其实就是static map,可以有多种维护方法
这里有个例子 https://www.cnblogs.com/qicosmos/p/5090159.html
我就不贴代码了,脑补一下就有了
static std::unordered_map<std::string,OptionTypeInfo>
lru_cache_options_type_info ={
{"capacity",
{offsetof(structLRUCacheOptions, capacity),OptionType::kSizeT,
OptionVerificationType::kNormal,OptionTypeFlags::kMutable}},
{"num_shard_bits",
{offsetof(structLRUCacheOptions, num_shard_bits),OptionType::kInt,
OptionVerificationType::kNormal,OptionTypeFlags::kMutable}},
{"strict_capacity_limit",
{offsetof(structLRUCacheOptions, strict_capacity_limit),
OptionType::kBoolean,OptionVerificationType::kNormal,
OptionTypeFlags::kMutable}},
{"high_pri_pool_ratio",
{offsetof(structLRUCacheOptions, high_pri_pool_ratio),
OptionType::kDouble,OptionVerificationType::kNormal,
OptionTypeFlags::kMutable}},
{"low_pri_pool_ratio",
{offsetof(structLRUCacheOptions, low_pri_pool_ratio),
OptionType::kDouble,OptionVerificationType::kNormal,
OptionTypeFlags::kMutable}},
};
直接注册也未尝不可,直观,适合聚集写法
依赖dlopen也可以,不过属于杀鸡牛刀
https://godbolt.org/z/jcqc38qqW
直接贴代码
#include <numeric>
#include <cmath>
#include <iostream>
classFloatingPointComparator{
private:
staticconstexprdouble DEFAULT_EPSILON =1e-10;
staticconstexprdouble MIN_NORMAL = std::numeric_limits<double>::min();
staticconstexprdouble MAX_NORMAL = std::numeric_limits<double>::max();
public:
// 基本的零值检查
static bool isZero(double value) {
return std::abs(value)< DEFAULT_EPSILON;
}
// 带自定义误差的零值检查
static bool isZeroWithEpsilon(double value, double epsilon) {
return std::abs(value)< epsilon;
}
// 相对误差检查
static bool isZeroRelative(double value) {
if(std::abs(value)< MIN_NORMAL){
returntrue;
}
return std::abs(value)< DEFAULT_EPSILON * std::max(1.0, std::abs(value));
}
// IEEE 754 特殊值检查
static bool isSpecial(double value) {
return std::isnan(value)|| std::isinf(value);
}
// 判断是否为正负零
static bool isExactZero(double value) {
return value ==0.0|| value ==-0.0;
}
// 综合判断
static bool isEffectivelyZero(double value) {
if(isSpecial(value)){
returnfalse;
}
if(isExactZero(value)){
returntrue;
}
returnisZeroRelative(value);
}
};
classZeroSignChecker{
public:
static bool isNegativeZero(double value) {
if(value !=0.0)returnfalse;
/*
union {
double d;
uint64_t u;
} u = {value};
return (u.u >> 63) == 1;
*/
auto u = std::bit_cast<std::uint64_t>(value);
// 检查符号位(最高位)
return(u >>63)==1;
}
static bool isPositiveZero(double value) {
if(value !=0.0)returnfalse;
/*
union {
double d;
uint64_t u;
} u = {value};
return (u.u >> 63) == 0;
*/
auto u = std::bit_cast<std::uint64_t>(value);
// 检查符号位
return(u >>63)==0;
}
static bool isPositiveZeroV2(double value) {
return value ==0.0&&!std::signbit(value);
}
static bool isNegativeZeroV2(double value) {
return value ==0.0&& std::signbit(value);
}
static bool isNegativeZeroCoreDump(double value) {
if(value !=0.0)returnfalse;
return std::isinf(1.0/ value)&&(1.0/ value <0);
}
static bool isPositiveZeroCoreDump(double value) {
if(value !=0.0)returnfalse;
return std::isinf(1.0/ value)&&(1.0/ value >0);
}
};
// 使用示例
void testZeroSign() {
double pzero =0.0;
double nzero =-0.0;
std::cout <<"Positive zero: "<<ZeroSignChecker::isPositiveZero(pzero)<< std::endl;
std::cout <<"Negative zero: "<<ZeroSignChecker::isNegativeZero(nzero)<< std::endl;
std::cout <<"Positive zero: "<<ZeroSignChecker::isPositiveZeroV2(pzero)<< std::endl;
std::cout <<"Negative zero: "<<ZeroSignChecker::isNegativeZeroV2(nzero)<< std::endl;
}
// 使用示例
void testFloatingPoint() {
double values[]={
0.0,
-0.0,
1e-15,
1e-10,
std::numeric_limits<double>::min(),
std::numeric_limits<double>::denorm_min(),
std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::infinity()
};
for(double val : values){
std::cout <<"Value: "<< val << std::endl;
std::cout <<"Is zero? "<<FloatingPointComparator::isEffectivelyZero(val)<< std::endl;
std::cout <<"Is special? "<<FloatingPointComparator::isSpecial(val)<< std::endl;
std::cout <<"Is exact zero? "<<FloatingPointComparator::isExactZero(val)<< std::endl;
std::cout <<"-------------------"<< std::endl;
}
}
int main() {
testFloatingPoint();
testZeroSign();
return0;
}
https://www.zhihu.com/question/2278762213/
主要原因 exit语义等同于从main 返回,会涉及到资源释放等相关流程,自然引入竞争问题
避免全局资源释放,使用quick_exit
另外直接列一下各种exit区别
https://learn.microsoft.com/en-us/previous-versions/6wdz5232(v=vs.140)
https://www.zhihu.com/question/1790209844/
msvc的log10f 和gcc libm的log10f行为不一样。大概实现算法有区别
两种结果都是符合标准的,毕竟round