#include <iostream> using namespace std; #include <string> #include <windows.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <map> const int maxval = 2000000 * 5; #include <unordered_map> void map_test() { printf("map_test\n"); map<int, int> mp; clock_t startTime, endTime; startTime = clock(); for (int i = 0; i < maxval; i++) { mp[rand() % maxval]++; } endTime = clock(); printf("%lf\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); printf("insert finish\n"); startTime = clock(); for (int i = 0; i < maxval; i++) { if (mp.find(rand()%maxval) == mp.end()) { //printf("not found\n"); } } endTime = clock(); printf("%lf\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); printf("find finish\n"); startTime = clock(); for(auto it = mp.begin(); it!=mp.end(); it++) { } endTime = clock(); printf("%lf\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); printf("travel finish\n"); printf("------------------------------------------------\n"); } void hash_map_test() { printf("hash_map_test\n"); unordered_map<int, int> mp; clock_t startTime, endTime; startTime = clock(); for (int i = 0; i < maxval; i++) { mp[rand() % maxval] ++; } endTime = clock(); printf("%lf\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); printf("insert finish\n"); startTime = clock(); for (int i = 0; i < maxval; i++) { if (mp.find(rand() % maxval) == mp.end()) { //printf("not found\n"); } } endTime = clock(); printf("%lf\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); printf("find finish\n"); startTime = clock(); for(auto it = mp.begin(); it!=mp.end(); it++) { } endTime = clock(); printf("%lf\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); printf("travel finish\n"); printf("------------------------------------------------\n"); } int main(int argc, char *argv[]) { srand(0); map_test(); Sleep(1000); srand(0); hash_map_test(); system("pause"); return 0; }
map(使用紅黑樹)與unordered_map(hash_map)比較
map理論插入、查詢時間複雜度O(logn)
unordered_map理論插入、查詢時間複雜度O(1)ios
數據量較小時,多是因爲unordered_map(hash_map)初始大小較小,大小頻繁到達閾值,屢次重建致使插入所用時間稍大。(相似vector的重建過程)。
哈希函數也是有消耗的(應該是常數時間),這時候用於哈希的消耗大於對紅黑樹查找的消耗(O(logn)),因此unordered_map的查找時間會多餘對map的查找時間。windows
數據量較大時,重建次數減小,用於重建的開銷小,unordered_map O(1)的優點開始顯現函數
數據量更大,優點更明顯測試
使用空間:優化
前半部分爲map,後半部分爲unordered_map
unordered_map佔用的空間比map略多,但能夠接受。
map和unordered_map內部實現應該都是採用達到閾值翻倍開闢空間的機制(1六、3二、6四、12八、25六、5十二、1024……)浪費必定的空間是不可避免的。而且在開雙倍空間時,若不能從當前開闢,會在其餘位置開闢,開好後將數據移過去。數據的頻繁移動也會消耗必定的時間,在數據量較小時尤其明顯。spa
一種方法是手寫定長開散列。這樣作在數據量較小時有很好地效果(避免了數據頻繁移動,真正趨近O(1))。但因爲是定長的,在數據量較大時,數據重疊嚴重,散列效果急劇降低,時間複雜度趨近O(n)。3d
一種折中的方法是本身手寫unordered_map(hash_map),將初始大小賦爲一個較大的值。擴張能夠模仿STL的雙倍擴張,也能夠本身採用其餘方法。這樣寫出來的是最優的,可是實現起來極爲麻煩。
綜合利弊,咱們組採用unordered_map。調試
附:使用Dev測試與VS2017測試效果相差極大???code
效率差了10倍???
緣由:
Devblog
VS2017
在Debug下,要記錄斷點等調試信息,的確慢。
Release:不對源代碼進行調試,編譯時對應用程序的速度進行優化,使得程序在代碼大小和運行速度上都是最優的。
VS2017切到release後,還更快
除了前面說的Debug與release致使效率差別外,編譯器的不一樣也會致使效率差別。 學到了。