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,

相关推荐
代码之光_198026 分钟前
保障性住房管理:SpringBoot技术优势分析
java·spring boot·后端
ajsbxi32 分钟前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
StayInLove1 小时前
G1垃圾回收器日志详解
java·开发语言
对许1 小时前
SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder“
java·log4j
无尽的大道1 小时前
Java字符串深度解析:String的实现、常量池与性能优化
java·开发语言·性能优化
羊小猪~~1 小时前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
小鑫记得努力1 小时前
Java类和对象(下篇)
java
binishuaio1 小时前
Java 第11天 (git版本控制器基础用法)
java·开发语言·git
zz.YE1 小时前
【Java SE】StringBuffer
java·开发语言
老友@1 小时前
aspose如何获取PPT放映页“切换”的“持续时间”值
java·powerpoint·aspose