STL Map的使用和性能issue

1、高效地访问

1)隐式插入问题

map初学者会直接用中括号访问,方便但是有代价:key不存在的时候还会隐式插入,

尤其对于LRU缓存设计,用这个就是灾难,会导致脏数据,

规避方案,cache的visit函数采用const修饰,同时采用下面的方案访问,

2)多遍历一次的性能问题

cpp 复制代码
Value LRUCache::Get(const KeyType& key, ValueType& value) {
    if (map_.count(key) > 0) {
        return map_[key];

    return ValueType();
}

Value LRUCache::Get(const KeyType& key, ValueType& value) {
    if (map_.find(key) != map_.end()) {
        return map_[key];

    return ValueType();
}

使用迭代器更高效,当map非常大的时候,差异更显著

cpp 复制代码
Value LRUCache::Get(const KeyType& key, ValueType& value) const {
    auto iter = map_.find(key);
    return iter == map_.end() ? ValueType() : iter->second;
}

2、insert失败的情况

insert返回是一个pair,支持两种类型。在实际工程项目中,很少见c++代码中处理insert失败的情况,

最近居然踩了一个坑,车道级渲染合批以后,没有道路了,

  • 深入分析结果是查找失败,但是insert也失败了。
  • 合批merge的时候,一种特别的case,导致了丢包的操作,mesh丢了,结果非常恶劣。。

key compare的问题,整个map不再是排序树了,示例代码如下,

comparator 的两种写法

cpp 复制代码
// 写法1
bool MergedMateriallKey::operator<(const MergedMateriallKey &o) const
{
	return color1 < o.color1 || color2 < o.color2 || tex < o.tex || mix_tex < o.mix_tex;
}
// 写法2
bool MergedMateriallKey::operator<(const MergedMateriallKey &o) const
{
    if (color1 != o.color1)
        return color1 < o.color1;
    if (color2 != o.color2)
        return color2 < o.color2;
    if (tex != o.tex)
        return tex < o.tex;

	return mix_tex < o.mix_tex;
}

主要差别点:

  • 写法1,分支太多,不是严格的排序树,
  • 写法2,只要color1不等就直接用他排序,用color2比较的唯一前提是color1相等了,

代码鲁棒的建议

key越少越好,2个int转化成一个long long,

字符串用hash值,或者转化成指针比较,

实在没招就diy结构体,key越少越好。

题外话

stl map的insert失败是静默的,返回值很容易被无效,

不像C#那么猛烈,如果key重复了直接抛异常exception,如果你不处理就直接crash,

相关推荐
阿让啊23 分钟前
C语言strtol 函数使用方法
c语言·数据结构·c++·单片机·嵌入式硬件
liulilittle1 小时前
OPENPPP2 —— IP标准校验和算法深度剖析:从原理到SSE2优化实现
网络·c++·网络协议·tcp/ip·算法·ip·通信
努力也学不会java1 小时前
【设计模式】 原型模式
java·设计模式·原型模式
方渐鸿1 小时前
【2024】k8s集群 图文详细 部署安装使用(两万字)
java·运维·容器·kubernetes·k8s·运维开发·持续部署
学亮编程手记1 小时前
K8S v1.33 版本主要新特性介绍
java·容器·kubernetes
Haven-2 小时前
Java-面试八股文-JVM篇
java·jvm·面试
我真的是大笨蛋3 小时前
JVM调优总结
java·jvm·数据库·redis·缓存·性能优化·系统架构
wjs0403 小时前
Git常用的命令
java·git·gitlab
superlls3 小时前
(算法 哈希表)【LeetCode 349】两个数组的交集 思路笔记自留
java·数据结构·算法
田里的水稻4 小时前
C++_队列编码实例,从末端添加对象,同时把头部的对象剔除掉,中的队列长度为设置长度NUM_OBJ
java·c++·算法