gpt4 book ai didi

c++ - 当许多 unordered_map 具有完全相同的字符串设置为键时如何节省内存

转载 作者:行者123 更新时间:2023-11-30 03:39:21 25 4
gpt4 key购买 nike

我正在使用特征进行分类。

每个功能组是 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 次从而节省内存?

附言:

我阅读了有关 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%。换享元后,CUP 利用率下降到 6~7%。毕竟,我的程序变得非常慢。

由于 string 的变化,我不知道为什么并行化不能正常工作至 flyweight_string .以及如何解决?

最佳答案

编辑

最下面是原来的答案内容,随着问题的更新,我正在全面修改。您可以将代码修改为

class FeatureGroup {
private:
enum{
c_n_a=0,
c_n_b,
...
num_features};
std::vector<double> features_;
}

您应该使用features(num_features) 初始化features。例如,要访问与 c_n_b 对应的功能,只需使用 features_[c_n_b]

这已经是您所能达到的最高效率了。事实上,您甚至不需要尝试缩短特征名称。


flyweight design pattern解释为

In computer programming, flyweight is a software design pattern. A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory.

这里好像很容易用boost::flyweight :

#include <iostream>
#include <unordered_map>

#include <boost/flyweight.hpp>

using fly_str = boost::flyweight<std::string>;

int main()
{
std::unordered_map<fly_str, int> m;
m[fly_str("hello")] = 2;
}

关于c++ - 当许多 unordered_map<string, double> 具有完全相同的字符串设置为键时如何节省内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38912009/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com