2014-04-09 68 views
0

快速問題: 使用數字ID和STL映射,C++會始終按照數字ID的順序遍歷這些對嗎?這可以根據編譯器進行更改,還是由STL規範保證?C++:std :: map數字ID的迭代排序 - 交叉編譯

例子:

#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]而不是map,它會對性能產生任何可想象的差異嗎?場景每秒鐘在地圖上迭代60次,其他各種事情都在進行。

編輯:感謝德里諾我有答案,但是測試表明,在地圖的元素數量少於數組的情況下,它可能會更好地依賴於元素的數量。請參閱下面使用的測試代碼來實現此目的,並且事先爲SDL代碼道歉,這比在C++中手動編寫我自己的毫秒函數更快。使用mingw的編譯,克++ 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毫秒陣列:14 NUM毫秒地圖:11

扭轉測試的順序沒有什麼區別。卸下注釋的地圖插入改變的結果爲以下: NUM毫秒陣列:14 NUM毫秒地圖:16

所以,在場景的地圖元素的數量是可變的或者甚至一半的可能達不到允許的最大數量,使用map而不是數組可能會使性能更高,因爲迭代映射的開銷在達到最大值時較小,但未達到最大值時的益處更大。

回答

2
  1. 是,該訂單將是相同的。 std :: map使用鍵的順序來存儲數據(在C++ 11中有unordered_map,它忽略了順序),所以當你遍歷它時,較小的先行。
  2. 對於這樣的小數據集,數組(或矢量或列表)將比地圖快得多。

[編輯:除地圖有較少元素(基準)的情況下。根據當前元素的數量,程序可能會比陣列快得多。]

2

您正在使用地圖將線性索引存儲爲鍵。只需使用vectorarray即可。您不應該關心存儲物品的訂單,它總是會以最有效的方式進行存儲,並且您不應該假設任何有關的事情。

您還可以插入到地圖是這樣的:

testmap[0] = "bob"; 

或者這樣:

testmap.insert(std::make_pair(1, "bob")); 
+0

在這種情況下,它將是一個數組,因爲矢量迭代器變得太容易失效。 請參閱原因如下爲什麼你認爲上面插入不太高性能: http://stackoverflow.com/questions/4286670/how-do-i-insert-into-a-map 還,你沒有回答我的任何一個問題,也不要以爲你知道我問他們的原因。如果我解釋他們,這個問題會更長,而且沒有目的。 – metamorphosis

+0

不要太過於自己。你沒有回答這個問題,你可能從我的評論中學到了一些東西。再見。 – metamorphosis