最近线上开发C++时,遇到一个性能问题,业务场景简单描述为:

给定m个商品ID, 4个特征(特征数量可增可减),已知商品对应的每个特征的值,如何快速获取某个商品的某个特征值?

当时我采取的是stl嵌套的数据结构,由于时间复杂度较高,且vector的值是随着map的rehash阶段不断进行内存拷贝的, 在全量计算特征的时候会给性能造成很大的压力,当时与base的性能对比如下:

性能不达标,无法上线,经过一番思考,最终采取了如下数据结构:

std::unordered_map<int64_t, float> FeatureKeyV;
std::vector<FeatureKeyV*> FeatureKeyValueVec;

其中,FeatureKeyV负责存储商品ID与特征值的对应关系,FeatureKeyValue每行代表一个特征,负责存储每个商品在该特征上的取值。在获取商品特征值时,首先获取该特征的行数i,得到FeatureKeyValue第i行的FeatureKeyV指针,最后根据商品id即可得到对应的特征值。整个检索过程的时间复杂度仅来源于哈希表的查找,众所周知,哈希表的特点就是查找效率高,时间复杂度为常数级别O(1)。

源码如下:

/*** 给定m个商品ID, 4个特征(特征数量可增可减),已知商品对应的每个特征的值,如何快速获取某个商品的某个特征值?*/
#include <iostream>
#include<unordered_map>enum {FEATURE_IREM_NUM_1=0,FEATURE_IREM_NUM_2,FEATURE_IREM_NUM_3,FEATURE_IREM_NUM_4,FEATURE_TOTAL_NUM
};
typedef std::unordered_map<int64_t, float> FeatureKeyV;
typedef std::vector<FeatureKeyV*> FeatureKeyValueVec;
FeatureKeyValueVec features;static const size_t NUM_DOC_ROW_NUM = 750;void Init()
{features.resize(FEATURE_TOTAL_NUM);for(size_t i = 0; i < features.size(); i++) {FeatureKeyV* &f = features[i];f = new FeatureKeyV(NUM_DOC_ROW_NUM);}
}
void SetFeature(int64_t sku, int fid, float value)
{if(fid > FEATURE_IREM_NUM_4 or fid < FEATURE_IREM_NUM_1)return;int i = fid - FEATURE_IREM_NUM_1;if(features[i])(*(features[i]))[sku] = value;
}
int GetFeature(int64_t sku, int fid, float &value)
{if(fid > FEATURE_IREM_NUM_4 or fid < FEATURE_IREM_NUM_1)return -1;int i = fid - FEATURE_IREM_NUM_1;if(features[i]){FeatureKeyV::iterator it = features[i]->find(sku);if (it == features[i]->end())return -1;value = it->second;return 0;}return -1;
}
void Reset()
{for(size_t i = 0; i < features.size(); i++){if(features[i]){features[i]->clear();delete features[i];}}
}
int main()
{Init();int64_t sku1 = 10000;SetFeature(sku1,FEATURE_IREM_NUM_1,20);SetFeature(sku1,FEATURE_IREM_NUM_2,30);SetFeature(sku1,FEATURE_IREM_NUM_3,40);SetFeature(sku1,FEATURE_IREM_NUM_4,50);int64_t sku2 = 10001;SetFeature(sku2,FEATURE_IREM_NUM_1,22);SetFeature(sku2,FEATURE_IREM_NUM_2,33);SetFeature(sku2,FEATURE_IREM_NUM_3,44);SetFeature(sku2,FEATURE_IREM_NUM_4,55);float value;if (!GetFeature(sku2, FEATURE_IREM_NUM_1, value)){cout << "feature:" << value << endl;}Reset();
}

优化后的性能对比如下:

性能达到上线标准,可见学好数据结构的重要性,有人曾经说过,一个优秀的算法,往往是利用最简单的数据结构解决最复杂的问题,如果数据结构设计比较复杂,那么一定是设计不合理。

C++ 数据结构实战:快速查找相关推荐

  1. 知识图谱实战应用16-知识图谱在化学物质结构上的应用,快速查找化学分子式与结构

    大家好,我是微学AI,今天给大家介绍一下知识图谱实战应用16-知识图谱在化学物质结构上的应用,快速查找化学分子式与结构.在化学领域,知识图谱可以应用于化学物质结构上.化学物质结构主要指分子结构和化学键 ...

  2. 数据结构-单链表进阶之快慢指针原理(快速查找法)

    面试题:快速找到未知长度单链表的中间节点? 这个问题的解决方法分为普通方法和高级方法. 1.普通方法即我们大家都能一下子想到的,首先遍历一遍获取总长度L,然后再次遍历循环至L/2即可:时间复杂度为: ...

  3. 面试被问,一千万个整数里面快速查找某个整数,你会怎么去做?

    最近小林在求职面试中被询问了这么一个有趣的面试题: 假设当我们需要在一千万个整数(整数的范围在1-1亿之间)里面快速查找某个整数是否存在于其中的话,如何快速查找进行判断会比较方便呢? ps: int ...

  4. python使用heapq快速查找最大或最小的 N 个元素

    python使用heapq快速查找最大或最小的 N 个元素 heapq实现了一个适合与Python的列表一起使用的最小堆排序算法. 堆是非线性的树形的数据结构,有两种堆,最大堆与最小堆.( heapq ...

  5. 01丨数据结构:快速的Redis有哪些慢操作

    Redis数据类型与底层数据类型关系 简单来说,底层数据结构一共有 6 种,分别是简单动态字符串.双向链表.压缩列表.哈希表.跳表和整数数组.它们和数据类型的对应关系如下图所示: 键和值的结构组织 为 ...

  6. windows xp https页面找不到_Windows 提权快速查找 Exp

    微软官方时刻关注列表网址: https://technet.microsoft.com/zh-cn/library/security/dn639106.aspx 比如常用的几个已公布的exp:KB25 ...

  7. 15 | 二分查找(上):如何用最省内存的方式实现快速查找功能?

    思考题:假设有 1000 万个整数数据,每个数据占 8 个字节,如何设计数据结构和算法,快速判断某个整数是否出现在这 1000 万数据中?希望不要占用太多的内存空间,最多不要超过 100MB 二分思想 ...

  8. 索引 Index -- 快速查找数据

    文章目录 1. 为什么需要索引 2. 索引的需求定义 2.1 功能性需求 2.2 非功能性需求 3. 构建索引常用的数据结构 4. 总结 索引这种常用的技术解决思路,底层往往会依赖哪些数据结构? 1. ...

  9. B-Tree/B+-Tree/二叉树/红黑树/Hash表/MySQL底层到底用哪个数据表建立索引做快速查找?

    B-Tree/B+-Tree/二叉树/红黑树/Hash表/MySQL底层到底用哪个数据表建立索引做快速查找? ~~B-Tree~~ ==B+Tree== ~~二叉树(Binary Search Tre ...

  10. d - 数据结构实验之查找四:二分查找_数据结构与算法笔记

    二分查找(上):如何用最省内存的方式实现快速查找功能? 二分查找(下):如何快速定位IP对应的省份地址? 变体一:查找第一个值等于给定值的元素 变体二:查找最后一个值等于给定值的元素 变体三:查找第一 ...

最新文章

  1. WMI技术介绍和应用——查询时间信息
  2. cassandra hbase_为什么选择Cassandra
  3. 信息论4—无失真信源编码(非延长码,霍夫曼编码)
  4. 2017/3/10 morning
  5. php投票系统中各个文件的作用说明,PHP开发简单投票系统之投票页面功能模块(二)...
  6. 基于TCP的在线聊天程序
  7. C# GDI+ 实现图片分隔
  8. python3中map的用法_python3中map()函数用法
  9. Uzi宣布退役:身体条件不允许再继续战斗了!
  10. Sentinel服务熔断配置fallback和blockHandler_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0052
  11. awk 正则表达式、正则运算符详细介绍
  12. warning: left shift count = width of type
  13. 四方支付系统,聚合平台搭建
  14. numpy 1.7中 f2py示例和说明文档
  15. 电场强度通量的高斯定理
  16. 5M的开源桌面整理软件,麻雀虽小,功能十分强大
  17. 奔 跑 吧 兄 弟 場 外 手 機 中 獎 活 動 是 真 的 嗎
  18. Spark自定义对象排序及自定义序列化
  19. 我终于深入参与了一个分布式系统了,好多想法不一样了
  20. 光影魔术手出现load XAR失败,解决办法。

热门文章

  1. 常用的坐标系及其EPSG编码
  2. 74cms 5.0.1 版本命令执行漏洞复现
  3. python调用qq互联_Django增加QQ第三方登录
  4. java调用萤石对讲_使用java封装萤石开放平台的接口
  5. Python单例模式的多种实现方式
  6. GPS的经纬度数据解析和转发
  7. 天创速盈:拼多多新店什么时候适合直通车?
  8. iOS动态库和静态库的运用
  9. 中国区块链专利申请数破万:阿里巴巴居首位 网心科技晋身前十
  10. 虚幻引擎4崩溃?10个UE4崩溃解决方法来了