C++ 在C+中更快地进行映射操作+;
在我的代码中,我在映射中存储不同组之间交互的参数集。目前,在启动时,我使用将两个组名合并为一个字符串而创建的键添加每个结构(C++ 在C+中更快地进行映射操作+;,c++,dictionary,associative-array,C++,Dictionary,Associative Array,在我的代码中,我在映射中存储不同组之间交互的参数集。目前,在启动时,我使用将两个组名合并为一个字符串而创建的键添加每个结构(testvals) string nKey = key1; nKey += JOIN_STRING; nKey += key2; map< string, struct> mymap_string; mymap_string.insert( make_pair(nKey, testval )); 在我的代码中,我在启动时创建了一次映射,但查找部分执行了数百
testvals
)
string nKey = key1;
nKey += JOIN_STRING;
nKey += key2;
map< string, struct> mymap_string;
mymap_string.insert( make_pair(nKey, testval ));
在我的代码中,我在启动时创建了一次映射,但查找部分执行了数百万次。我想知道是否有更好的方法来实现这一点,因为字符串连接似乎相对昂贵,而查找可能不是搜索和比较字符串的最快方法
我的测试似乎表明字符串比使用std::pair
作为映射键要快。我看了map
vsunordered\u map
,但似乎没有太大区别<当键的数量较大时,代码>无序_映射可能会稍微快一点
有人对什么可能是更好、更快的方法有什么建议吗?考虑到打这个电话的次数,如果我能大大加快速度,我可以节省很多时间。我不介意插入或设置是否快速,因为它只发生一次,但查找很重要。最好使用在Windows和Linux上工作的标准设备
更新:
好的,从这些问题来看,似乎需要更多的背景信息
testvals
是当前使用模型的输入参数的双精度结构,其中提供的变量数量将随模型而变化。但这通常在4-10个值之间。此处显示了一个典型的集合:
typedef struct
{
double m_temp_min;
double m_temp_max;
double m_liquid_content;
double m_growth_rate;
double m_alpha;
double m_beta;
} testvals;
Key1和Key2始终是从程序核心模块传递的字符串,但这些字符串是用户定义的,这意味着它们可以是从“a”
到“my_big\u yellow\u subside\u 3”
的任何字符串
地图中的键数取决于数据中的组数。如果只需要为两个组提供交互参数,则映射将只有4个唯一的字符串键:group1~~group1
、group1~~group2
、group2~~group1
和group2~~group2
。通常,地图中有3或4种组类型,因此键的数量通常为十。这个尺寸可能就是我看不出map
和unordered\u map
性能有多大差异的原因
其中一条评论提到了std::pair
,正如我最初所说的,调用make_pair()
的成本似乎比生成字符串的成本要高得多,并且在测试时慢了50%以上。但是我没有尝试将std::pair
与unordered\u map
组合。我假设如果std::pair
使用map时速度较慢,那么unordered_map
时速度也会较慢。有没有理由期待它会有很大的不同
我希望这有助于澄清一些问题。您的密钥数量有限,这使得计算散列比实际查找更昂贵。这就是为什么在您的案例中,
std::map
和std::unordered_map
没有太大不同。除此之外,JOIN\u STRING
在计算哈希或比较字符串时还引入了不必要的操作
我建议您完全避免使用这些组名,而是使用组ID。对于N组类型,您只有N2种不同类型的交互。那么ID将属于[0,N]的范围。如果N在编译时已知,您甚至可以将其设置为数组
string nKey = key1;
nKey += JOIN_STRING;
nKey += key2;
你将使用
std::vector<testvals> vals(N*N); // vector with N² elements
uint32_t nKey = key1*N + key2; // index of the <key1, key2> mapping
const auto &val = vals[nKey]; // get the mapped value
<> P>不需要在代码中使用“<代码> TyPulf< /Case> C++中的代码结构。也可以使用<代码> STD::代码< >代码:STD::MAP<代码>从ID到名称。ID可以是一个较小的类型,如代码> UTI8GYT 或
std::map
和std::unordered\u map
在您的情况下没有太大不同。此外,JOIN\u STRING
在计算哈希或比较字符串时也引入了不必要的操作
我建议您完全避免使用这些组名,而是使用组ID。对于N个组类型,您只有N2种不同类型的交互。那么ID将属于[0,N]的范围。如果在编译时知道N,您甚至可以将其设置为数组。因此
string nKey = key1;
nKey += JOIN_STRING;
nKey += key2;
你将使用
std::vector<testvals> vals(N*N); // vector with N² elements
uint32_t nKey = key1*N + key2; // index of the <key1, key2> mapping
const auto &val = vals[nKey]; // get the mapped value
< >不必使用C++中的“代码”> TyPufF代码中的结构。也可以使用<代码> STD::“代码< >代码>:STD::MAP>代码>从ID到名称。ID可以是一个较小的类型,如“代码> UTI8GYT 或
key1
和key2
具体采用哪种类型的值?我会尝试为键定义一个自定义类型,以及一个严格的弱排序比较器,以便有效地使用两个离散字符串作为键。为了获得额外的积分,键将包括对包含std::variant
的std::reference\u wrapper
进行de,以便在不复制字符串的情况下构造用于查找目的的临时键。unordered\u map
将比map
更快,因为内部表示是O(1)
查找的哈希表(假设有足够的容量和负载系数),而map
通常是某种形式的搜索树,用于查找O(logn)
查找时应始终比map
快-因此,如果map
快,则w.r.t.会发生一些低效的情况。您的密钥是如何查找的。@Slava您阅读了完整的问题吗?@jpmorr关于这一点的最后一个想法您可能会考虑。当您有一个有序的字符串映射时,