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,

相关推荐
释厄6238 分钟前
同性线套娃律——圆面积必然=1+2+...+n 的求和·圆心不与 π 相关
java·人工智能·算法·1024程序员节
暴力求解25 分钟前
C++ ---继承(二)
开发语言·c++·算法
猫猫.15329 分钟前
IO、存储、硬盘、文件系统详细总结
java·java-ee
SL_staff1 小时前
设备离线时业务不中断:JVS-IOT高可用架构解析
java·物联网·产品
郭小李1 小时前
mybatis 动态 sql
java·sql·mybatis
瑞码空间1 小时前
JSP与Servlet核心开发与CRUD实战笔记
java·笔记·servlet·jsp
知守观1 小时前
技术考古:iBATIS 2.3.4 时代的持久层,是如何用 Map 玩转 307 个存储过程的?
java·后端·mybatis
captain3762 小时前
MyBatis Plus(1)
java·服务器·mybatis
香蕉大香蕉(06敬畏市场)2 小时前
MySQL 单点详解(08)
java·数据库·mysql·面试·八股
thefool1122663 小时前
HTTPS协议
java