【发布时间】:2016-08-12 07:13:31
【问题描述】:
我正在使用特征进行分类。
每个功能组都是unordered_map<string, double>。 string 是特征名称,double 是特征值。
class FeatureGroup {
private:
unordered_map<string, double> features_ = unordered_map<string, double>{
{ "c_n_a", 0 },
{ "c_n_b", 0 },
{ "l_1_a_1mm", 0 },
{ "l_2_a_1mm", 0 },
{ "l_3_a_1mm", 0 },
...
}
}
每个实例都有一个功能组。 而且,我有很多(比如说 8000000)个实例。
我的问题是:我想不费吹灰之力地节省内存。正如你所说,我已经在使用简短的功能名称了。
由于每个实例的特征名称在实验中是相同的,我不希望像“c_n_a”、“c_n_b”这样的特征名称字符串被存储 8000000 次。
我已经做了一些搜索(比如使用 char* 作为 Key 类型,std::reference_wrapper),但还是一头雾水。所以,请帮忙。我应该怎么做才能不存储功能名称 8000000 次从而节省内存?
PS:
我阅读了有关flyweight 的内容,但没有发现它不应该工作。但是,在我如下更改代码后,我的程序变得非常缓慢。
using flyweight_string = boost::flyweight<std::string>;
class FeatureGroup {
private:
unordered_map<flyweight_string, double> features_ = unordered_map<flyweight_string, double>{
{ flyweight_string("c_n_a"), 0 },
{ flyweight_string("c_n_b"), 0 },
{ flyweight_string("l_1_a_1mm"), 0 },
{ flyweight_string("l_2_a_1mm"), 0 },
{ flyweight_string("l_3_a_1mm"), 0 },
{ flyweight_string("l_1_b_1mm"), 0 },
...
}
}
在设置和获取特征时,我使用如下格式:
features_[flyweight_string(feature_name)] // feature_name is of string type
在设置特征值的时候,我也使用了下面这句话来检查特征名称是否被定义。如果没有,程序exit(1)。
if(features_.find(flyweight_string(feature_name)) != features_.end())
我的程序结构如下。我希望有人能找到使用 boost::flyweight 后变慢的原因。
在我的程序中,每个 Instance(类)都有一个 ID、FeatureGroup 和类标签。我有另一个名为InstanceManager 的类,它实际上维护了一个实例容器(即unordered_set<Instance>)。
在我的程序中,我为所有实例计算每个特征,例如一次为所有实例计算"c_n_a",然后更新存储在容器中的相应特征值。在计算完所有特征值之后,我得到每个实例的特征值,并使用经过训练的模型来预测类标签。
实例特征值的设置和获取使用OpenMP为实例容器并行化。
在 Windows 性能监视器中,在更改为 boost::flyweight<std::string> 之前,所有 CPU 内核的利用率几乎为 100%。改成蝇量级后,CUP利用率下降到6~7%。毕竟,我的程序变得非常慢。
我不知道为什么由于从string 更改为flyweight_string,并行化无法正常工作。还有,如何解决?
【问题讨论】:
-
使用字符串数组来存储特征名称并将其声明为常量。
-
你查看trie了吗?
-
您的问题与标题不符。您不能拥有与地图中的键完全相同的字符串,除非它是多地图,但事实并非如此。
-
所以你的键总是一样的,但是值会随着实例的变化而变化——是这样吗?像这样: map
features_one = { {"key1":1 },{"key2":0.3 },{"key3":0.2 },{"key4":3 }} ; map features_two = { {"key1":0.1 },{"key2":0.35 },{"key3":0.12 },{"key4":0.33 }} 。是这样吗? -
@MiroRodozov ,正如您所说,键始终相同,只是值因实例而异。我选择使用 unordered_map
而不是 vector 来表示特征值,因为我想节省打字工作并使特征值的访问更加直观。
标签: c++ string memory unordered-map