c++:std::map数字id的迭代排序-交叉编译器
c++: std::map iterative ordering for numeric ids - cross-compiler
快速问题:使用数字id和STL映射,C++是否总是按照数字id的顺序迭代这些对?这种变化可能取决于编译器,还是由STL规范保证?
示例:
#include <iostream>
#include <map>
#include <string>
int main(int argc, char **argv)
{
std::map<int, std::string> testmap;
testmap.insert(std::map<int, std::string>::value_type(0, "bob"));
testmap.insert(std::map<int, std::string>::value_type(1, "jean"));
testmap.insert(std::map<int, std::string>::value_type(2, "melissa"));
testmap.insert(std::map<int, std::string>::value_type(3, "george"));
testmap.insert(std::map<int, std::string>::value_type(4, "dave"));
testmap.insert(std::map<int, std::string>::value_type(5, "sally"));
testmap.insert(std::map<int, std::string>::value_type(6, "jessica"));
testmap.insert(std::map<int, std::string>::value_type(7, "sandy"));
testmap.insert(std::map<int, std::string>::value_type(8, "winston"));
testmap.insert(std::map<int, std::string>::value_type(9, "pete"));
testmap.insert(std::map<int, std::string>::value_type(10, "maxx"));
for (std::map<int, std::string>::iterator map_item = testmap.begin(); map_item != testmap.end(); map_item++)
{
std::cout << map_item->second << std::endl;
}
std::cin.get();
return 0;
}
我把这些对按哪个顺序加进去并不重要,它们总是以数字顺序出现在G++中。编译器之间的情况会相同吗?
其次,考虑到映射的大小很小,如果我迭代std::string数组[11]而不是映射,会对性能产生任何可能的影响吗?场景是每秒在地图上迭代60次,同时进行各种其他事情
编辑:多亏了Drino,我得到了答案,但测试表明,在映射的元素比数组少的情况下,它的性能可能会更好,这取决于元素的数量。请参阅下面用于实现这一点的测试代码,并提前为SDL代码道歉,它比用C++手工编写我自己的毫秒函数更快。使用mingw,g++4.8,-O2:编译
std::map<int, std::string> testmap;
std::string testarray[11];
testmap.insert(std::map<int, std::string>::value_type(0, "bob"));
// testmap.insert(std::map<int, std::string>::value_type(1, "jean"));
// testmap.insert(std::map<int, std::string>::value_type(2, "melissa"));
// testmap.insert(std::map<int, std::string>::value_type(3, "george"));
// testmap.insert(std::map<int, std::string>::value_type(4, "dave"));
// testmap.insert(std::map<int, std::string>::value_type(5, "sally"));
testmap.insert(std::map<int, std::string>::value_type(6, "jessica"));
testmap.insert(std::map<int, std::string>::value_type(7, "sandy"));
testmap.insert(std::map<int, std::string>::value_type(8, "winston"));
testmap.insert(std::map<int, std::string>::value_type(9, "pete"));
testmap.insert(std::map<int, std::string>::value_type(10, "maxx"));
testarray[0] = "bob";
testarray[1] = "jean";
testarray[2] = "melissa";
testarray[3] = "george";
testarray[4] = "dave";
testarray[5] = "sally";
testarray[6] = "jessica";
testarray[7] = "sandy";
testarray[8] = "winston";
testarray[9] = "pete";
testarray[10] = "maxx";
SDL_Delay(2000); // Delay introduced to negate background effects of window creation and executable overhead
Uint32 sdltime = SDL_GetTicks();
unsigned int counter = 0;
for (unsigned int looper = 0; looper != 100000; looper++)
{
for (unsigned int arrpos = 0; arrpos != 11; arrpos++)
{
if (testarray[arrpos] == "maxx")
{
counter++; // Included so the compiler doesn't optimise the loop out of existence.
}
}
}
std::cout << "num milliseconds array:" << SDL_GetTicks() - sdltime << std::endl;
SDL_Delay(2000); // Delay introduced to negate background effects of buffer out
sdltime = SDL_GetTicks();
counter = 0;
for (unsigned int looper = 0; looper != 100000; looper++)
{
for (std::map<int, std::string>::iterator map_item = testmap.begin(); map_item != testmap.end(); map_item++)
{
if (map_item->second == "maxx")
{
counter++; // Included so the compiler doesn't optimise the loop out of existence.
}
}
}
std::cout << "num milliseconds map:" << SDL_GetTicks() - sdltime << std::endl;
在这台机器上,它通常会输出:num毫秒数组:14num毫秒映射:11
颠倒测试顺序没有什么区别。删除注释掉的映射插入会将结果更改为以下内容:num毫秒数组:14num毫秒映射:16
因此,在映射元素的数量是可变的,或者可能甚至达不到允许的最大数量的一半的情况下,使用映射而不是数组可能更有性能,因为当达到最大值时迭代映射的开销很小,但当未达到最大值时利益更大。
- 是的,订单是一样的。std::map使用键的顺序来存储数据(在C++11中有一个unrdered_map,它忽略了顺序),所以当你迭代它时,较小的优先
- 对于这样小的数据集,数组(或向量或列表)将比映射快得多
[EDIT:除非映射的元素较少(基准)。根据存在的元素数量,程序在映射上的迭代速度可能比数组快得多。]
您使用映射将线性索引存储为键。只需使用vector
或array
。你不应该关心map
存储物品的顺序,它总是会以最有效的方式进行,你不应该对此承担任何责任。
你也可以这样插入地图:
testmap[0] = "bob";
或者像这样:
testmap.insert(std::make_pair(1, "bob"));
相关文章:
- 保证编译器指令在C++中重新排序
- 使用动态数组对算法编译器错误进行排序
- C STD ::排序Intel编译器错误:访问违规
- 编译器跨静音边界重新排序的代码
- 编译器说明重新排序
- 在 for 循环中重新排序测试条件:编译器错误?
- 与英特尔相比,GNU C++编译器在对向量进行排序时性能较差
- 数据与C++ std::future竞争.编译器重新排序
- 涉及编译器重新排序的优化示例
- 为什么编译器不强制保留排序规则?
- 编译器重新排序与内存重新排序
- 是否使用 Guard 类免受编译器优化和 CPU 重新排序的影响
- visual编译器指令在C++中重新排序优化(以及禁止它们的原因)
- 在这种情况下,编译器可以根据自己的意愿对指令进行重新排序
- as-if规则是否防止编译器对全局/成员变量的访问重新排序
- C/ c++编译器会对交换运算符(例如:+,*)重新排序以优化常量吗?
- 我能保证c++编译器不会重新排序我的计算吗?
- 我的编译器会重新排序这个表达式吗?
- (A+B+C)≠(A+C+B)以及编译器重新排序
- c++:std::map数字id的迭代排序-交叉编译器