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,

相关推荐
moringlightyn4 小时前
c++ 智能指针
开发语言·c++·笔记·c++11·指针·智能指针
执笔论英雄4 小时前
【大模型推理】ScheduleBatch 学习
java·spring boot·学习
Code_Shark4 小时前
AtCoder Beginner Contest 424 题解
数据结构·c++·算法·数学建模·青少年编程
CRMEB系统商城5 小时前
【新版发布】标准版PHP v5.6.4正式版,优化部分用户体验
java·大数据·小程序·php·ux
今天又在学代码写BUG口牙5 小时前
MFC应用程序,工作线程学习记录
c++·mfc·1024程序员节
青云交5 小时前
Java 大视界 -- Java 大数据在智慧养老服务需求分析与个性化服务匹配中的应用
java·需求分析·智慧养老·健康管理·java 大数据·个性化服务·生活照料
j_xxx404_5 小时前
C++ STL简介:从原理到入门使用指南
开发语言·c++
15Moonlight5 小时前
06-MySQL基础查询
数据库·c++·mysql·1024程序员节
Dream it possible!5 小时前
LeetCode 面试经典 150_链表_反转链表 II(60_92_C++_中等)(头插法)
c++·leetcode·链表·面试
丈剑走天涯5 小时前
kubernetes 源码编译(ubuntu) kubernetes-1.34.1
java·容器·kubernetes·1024程序员节