欢迎关注更多精彩
关注我,学习常用算法与数据结构,一题多解,降维打击。
问题提出
在很多工业软件中,需要对对象进行微分细化,这样会产生很多(几百万到几千万)对象。随着业务的发展,对象内的数据也会越来越多,导致内存成高不下。
class Property1;
class Property2;
class Element {
int x, y; // 基础数据
int length; // 基础数据
bool selected; // 基础数据
Property1 p1; // 业务数据
Property2 p2; // 业务数据
...
};
以上面的class 为例, 基础数据是程序一直要用的。业务数据可能是在某个过程使用为中间过程数据。
一般会创建很多个Element
vector 表示 。
p1, p2也都被被动创建了。带来了很多内存浪费
优化思路
利用内存排布原理
每个变量总是从自身长度的整数倍地址开始排布。
可以按照size小到大的数据排列。
使用内存压缩机制
bool 类型的数据是占用一个字节,但只使用1位就可以表示true, false。这里存在了内存浪费。
又比如uint类型,但是数据大小最大是16, 可以使用5位就可以表示。
C++ 高版本支持位数设定。
bool selected : 1; // 代表只使用其中1位
uint enum_type : 5; // 代表只使用其中5位,业务最大值存储值为16
使用指针管理业务数据
使用智能指针管理
class Property1;
class Property2;
class Element {
int x, y; // 基础数据
int length; // 基础数据
bool selected; // 基础数据
shared_ptr<Property1> p1; // 业务数据
shared_ptr<Property2> p2; // 业务数据
...
};
shared_ptr<Property1> Element::GetP1() {
if (p1==NULL) p1 = make_shared<Property1>();
return p1;
}
由于是在堆上申请空间,上述方法GetP1调用数量大时,可能会导致花多时间在make_shared上。
可以利用缓存池的概念,考虑事先申请好比较多的内存,然后通过指针或索引的方式来访问。
vector<Element> eles;
vector<Property1> p1s;
void newP1() {
if(!p1s.empty()) return;
p1s.resize(eles.size());
}
当有必要时调用newP1(); 只申请一次内存节省了重复申请内存的时间。
通过p1s[i]访问。
本人码农,希望通过自己的分享,让大家更容易学懂计算机知识。