我正在使用功能进行分类。
每个功能组均为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 },
...
}
}
每个实例都有一个功能组。而且,我有很多(比方说800万个)实例。
我的问题是:我想节省很多精力。可以说,我已经使用了简短的功能名称。
由于每个实例的功能名称在实验中是相同的,因此我不希望将诸如“ c_n_a”,“ c_n_b”之类的功能名称字符串存储8000000次。
我已经做了一些搜索(例如使用char *作为键类型,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
,它实际上维护了Instance(即unordered_set<Instance>
)的容器。在我的程序中,我为所有实例(例如,一次为所有实例)计算每个功能"c_n_a"
,然后更新存储在容器中的相应功能值。在计算完所有特征值之后,我将获得每个实例的特征值,并使用经过训练的模型来预测类标签。
使用OpenMP为实例容器对实例的特征值进行设置和获取。
在Windows性能监视器中,在更改为之前boost::flyweight<std::string>
,所有CPU内核的利用率都接近100%。改变举重后,银联的利用率下降到6〜7%。毕竟,我的程序变得非常慢。
我不知道为什么由于从string
到的更改,并行化无法正常工作flyweight_string
。而且,如何解决呢?
看起来您有能力将功能名称硬编码到源代码中。如果是这样,则根本不应该使用字符串-而是使用一个枚举:
enum class FeatureName { c_n_a, c_n_b, l_1_a_1mm, l_2_a_1mm, l_3_a_1mm, ... };
class FeatureGroup {
private:
std::unordered_map<FeatureName, double> features_ =
std::unordered_map<FeatureName, double> {
{ FeatureName::c_n_a, 0 },
{ FeatureName::c_n_b, 0 },
{ FeatureName::l_1_a_1mm, 0 },
{ FeatureName::l_2_a_1mm, 0 },
{ FeatureName::l_3_a_1mm, 0 },
...
}
}
您可能需要在FeatureName
和字符串之间进行转换的函数。有很多有关如何执行此操作的示例。请注意,枚举数的长度对程序的内存使用量没有影响,因此可以负担得起,只要您需要它们就可以轻松阅读。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句