最近在學習緩存方面的知識,瞭解了緩存(Cache)的基本概念,爲何要使用緩存,以及一些緩存算法(緩存替換),如LRU、LFU、ARC等等。算法
這些緩存算法的實現過程會使用一些基本的數據結構,如list、map等。STL提供了一些標準的容器模板類能夠拿來使用,我要在QT環境下測試,因此就近學習一下QT的容器類,如QList、QMap等。緩存
可在QT官方幫助文檔中關鍵詞搜索「Container Classes」安全
這些容器類的設計比STL容器更輕,更安全,更易於使用。 若是您不熟悉STL,或者喜歡以「Qt方式」執行操做,則能夠使用這些類而不是STL類。數據結構
這些容器類是隱式共享的,它們是可重用的,而且它們針對速度,低內存消耗和最小內聯代碼擴展進行了優化,從而致使較小的可執行文件。 此外,它們在用於訪問它們的全部線程用做只讀容器的狀況下是線程安全的。dom
爲了遍歷存儲在容器中的項,能夠使用兩種類型的迭代器之一:Java樣式迭代器和STL樣式迭代器。 Java樣式的迭代器更易於使用並提供高級功能,而STL樣式的迭代器更輕更高效,能夠將Qt和STL的通用算法一塊兒使用。函數
Qt還提供了一個foreach關鍵字,能夠很容易地迭代存儲在容器中的全部項目。學習
除了通用的容器類以外,Qt還包括三個模板類,在某些方面相似於容器。 這些類不提供迭代器,不能與foreach關鍵字一塊兒使用。其中的一個模板類就是QCache。測試
QCache<Key, T>提供緩存以存儲與鍵Key類型的鍵相關聯的特定類型T的對象。優化
例如,下面的代碼定義了一個緩存,裏面存儲的鍵是一個整數,值是咱們自定義的Employee類型:spa
QCache<int, Employee> cache;
如下是如何在緩存中插入對象:
1
2 3 4 5 |
Employee *employee =
new
Employee; employee->setId( 37 ); employee->setName( "Richard Schmit" ); ... cache.insert(employee->id(), employee); |
使用QCache優於其它基於鍵key的數據結構(例如QMap或QHash)的地方主要表如今於QCache會自動獲取插入到緩存中的對象的全部權,並刪除它們以在必要時爲新對象騰出空間。 將對象插入緩存時,能夠指定其成本(cost),該成本應與對象佔用的內存量具備某種近似關係。 當全部對象的成本(totalCost())的總和超過緩存的限制(maxCost())時,QCache就開始刪除緩存中的對象以保持在限制之下,刪除操做從最近訪問較少的對象開始(內部的緩存淘汰機制)。
默認狀況下,QCache的maxCost()爲100。您能夠在QCache構造函數中指定不一樣的值:
QCache<int, MyDataStructure> cache(5000);
每次調用insert()時,均可以將cost指定爲第三個參數(在鍵和要插入的對象的指針插入以後)。 在調用以後,插入的對象由QCache擁有,QCache能夠隨時刪除它覺得其它對象騰出空間。
要在緩存中查找對象,請使用object()或operator []()。 此函數經過其鍵key查找對象,並返回指向緩存對象(由緩存擁有)的指針或空指針。
若是要從緩存中刪除特定鍵的對象,請調用remove(), 這也將刪除該對象。 若是要在沒有QCache刪除的狀況下從緩存中刪除對象,請使用take()。
至於,其餘的操做,和普通容器相似。好比,
使用clear() 函數來釋放緩存中全部的對象。
使用contains() 函數判斷當前緩存中是否包含某個key。
使用count() 或 size() 函數得到當前緩存中保存的對象的個數。
使用isEmpty() 函數判斷當前緩存是否包含有對象。
使用keys()函數獲取當前緩存中的key列表。
使用setMaxCost ()函數設置緩存的最大容許總成本,若是當前總成本大於要設置的成本,則會當即刪除某些對象。
下面是我實驗的一個例子:
Employee有三個成員變量:訪問次數access、id和名字name,並有其對應的seter和geter函數。
id和name經過隨機數來產生,初始化cache爲空並設置maxCost,若是能在緩存中找到id則訪問次數access加1,不然就將其加入到緩存中去。
當達到最大maxCost數量時,QCache內部會淘汰掉最近訪問較少的對象(即access次數較少的對象)。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
#include
<QCoreApplication> #include <QRandomGenerator> #include <QCache> #include <QList> #include <QDebug> class Employee { public : Employee() { m_nAccess = 0 ; } Employee( int nId, QString strName) { m_nAccess = 0 ; m_nId = nId; m_strName = strName; } ~Employee() { } int id() { return m_nId; } int access() { return m_nAccess; } QString name() { return m_strName; } void setId( int nId) { m_nId = nId; } void setName(QString strName) { m_strName = strName; } void addAccess() { m_nAccess++; } private : int m_nAccess; // 被訪問次數 int m_nId; // id QString m_strName; // 名字 }; int main( int argc, char *argv[]) { QCoreApplication a(argc, argv); // By default, QCache's maxCost() is 100. You can specify a different value in the QCache constructor QCache< int , Employee> cache( 5 ); int nCount = 0 ; while (nCount < 50 ) { int nRandomId = QRandomGenerator::global()->bounded( 10 ); qDebug() << "\nRequest =" << nRandomId; QString strRandomName = QString::number(QRandomGenerator::global()->bounded( 100 )); Employee *pEmployee = new Employee(nRandomId, strRandomName); // 在緩存中查找 Employee *pEmployeeTmp = cache.object(nRandomId); if (pEmployeeTmp != nullptr) { // 找到了... qDebug() << "find ID =" << pEmployeeTmp->id() << "Name =" << pEmployeeTmp->name(); pEmployeeTmp->addAccess(); } else { // 沒找到,則將其插入到緩存中去 cache.insert(pEmployee->id(), pEmployee); } // 查看當前緩存中的狀況 QList< int > keys = cache.keys(); qDebug() << "size of cache = " << keys.size(); for ( int i = 0 ; i < keys.size(); ++i) { int nId = keys.at(i); Employee *pEmployee = cache.object(nId); qDebug() << "ID =" << nId << \ "Name =" << pEmployee->name() << \ "Access =" << pEmployee->access(); } nCount++; } return a.exec(); } |
輸出結果:隨着不斷訪問,緩存中訪問最多的對象會保留,訪問較少的的對象可能會被刪除淘汰掉!
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 |
Request = 2 size of cache = 1 ID = 2 Name = "69" Access = 0 Request = 7 size of cache = 2 ID = 2 Name = "69" Access = 0 ID = 7 Name = "93" Access = 0 Request = 9 size of cache = 3 ID = 9 Name = "98" Access = 0 ID = 2 Name = "69" Access = 0 ID = 7 Name = "93" Access = 0 Request = 6 size of cache = 4 ID = 9 Name = "98" Access = 0 ID = 2 Name = "69" Access = 0 ID = 7 Name = "93" Access = 0 ID = 6 Name = "24" Access = 0 Request = 0 size of cache = 5 ID = 9 Name = "98" Access = 0 ID = 2 Name = "69" Access = 0 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 0 ID = 6 Name = "24" Access = 0 Request = 1 size of cache = 5 ID = 2 Name = "69" Access = 0 ID = 1 Name = "29" Access = 0 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 0 ID = 6 Name = "24" Access = 0 Request = 3 size of cache = 5 ID = 3 Name = "54" Access = 0 ID = 1 Name = "29" Access = 0 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 0 ID = 6 Name = "24" Access = 0 Request = 6 find ID = 6 Name = "24" size of cache = 5 ID = 3 Name = "54" Access = 0 ID = 1 Name = "29" Access = 0 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 0 ID = 6 Name = "24" Access = 1 Request = 7 find ID = 7 Name = "93" size of cache = 5 ID = 3 Name = "54" Access = 0 ID = 1 Name = "29" Access = 0 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 1 ID = 6 Name = "24" Access = 1 Request = 1 find ID = 1 Name = "29" size of cache = 5 ID = 3 Name = "54" Access = 0 ID = 1 Name = "29" Access = 1 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 1 ID = 6 Name = "24" Access = 1 Request = 9 size of cache = 5 ID = 9 Name = "36" Access = 0 ID = 1 Name = "29" Access = 1 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 1 ID = 6 Name = "24" Access = 1 Request = 7 find ID = 7 Name = "93" size of cache = 5 ID = 9 Name = "36" Access = 0 ID = 1 Name = "29" Access = 1 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 1 Request = 1 find ID = 1 Name = "29" size of cache = 5 ID = 9 Name = "36" Access = 0 ID = 1 Name = "29" Access = 2 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 1 Request = 9 find ID = 9 Name = "36" size of cache = 5 ID = 9 Name = "36" Access = 1 ID = 1 Name = "29" Access = 2 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 1 Request = 5 size of cache = 5 ID = 1 Name = "29" Access = 2 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 1 ID = 5 Name = "7" Access = 0 Request = 1 find ID = 1 Name = "29" size of cache = 5 ID = 1 Name = "29" Access = 3 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 1 ID = 5 Name = "7" Access = 0 Request = 5 find ID = 5 Name = "7" size of cache = 5 ID = 1 Name = "29" Access = 3 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 1 ID = 5 Name = "7" Access = 1 Request = 6 find ID = 6 Name = "24" size of cache = 5 ID = 1 Name = "29" Access = 3 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 2 ID = 5 Name = "7" Access = 1 Request = 4 size of cache = 5 ID = 4 Name = "1" Access = 0 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 2 ID = 5 Name = "7" Access = 1 Request = 5 find ID = 5 Name = "7" size of cache = 5 ID = 4 Name = "1" Access = 0 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 2 ID = 5 Name = "7" Access = 2 Request = 4 find ID = 4 Name = "1" size of cache = 5 ID = 4 Name = "1" Access = 1 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 2 ID = 5 Name = "7" Access = 2 Request = 6 find ID = 6 Name = "24" size of cache = 5 ID = 4 Name = "1" Access = 1 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 3 ID = 5 Name = "7" Access = 2 Request = 2 size of cache = 5 ID = 2 Name = "28" Access = 0 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 3 ID = 5 Name = "7" Access = 2 Request = 6 find ID = 6 Name = "24" size of cache = 5 ID = 2 Name = "28" Access = 0 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 2 Request = 8 size of cache = 5 ID = 8 Name = "44" Access = 0 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 2 Request = 5 find ID = 5 Name = "7" size of cache = 5 ID = 8 Name = "44" Access = 0 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 4 size of cache = 5 ID = 4 Name = "90" Access = 0 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 2 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 7 find ID = 7 Name = "93" size of cache = 5 ID = 4 Name = "90" Access = 0 ID = 0 Name = "50" Access = 0 ID = 7 Name = "93" Access = 3 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 0 find ID = 0 Name = "50" size of cache = 5 ID = 4 Name = "90" Access = 0 ID = 0 Name = "50" Access = 1 ID = 7 Name = "93" Access = 3 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 8 size of cache = 5 ID = 8 Name = "74" Access = 0 ID = 0 Name = "50" Access = 1 ID = 7 Name = "93" Access = 3 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 9 size of cache = 5 ID = 9 Name = "51" Access = 0 ID = 0 Name = "50" Access = 1 ID = 7 Name = "93" Access = 3 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 3 size of cache = 5 ID = 3 Name = "23" Access = 0 ID = 0 Name = "50" Access = 1 ID = 7 Name = "93" Access = 3 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 7 find ID = 7 Name = "93" size of cache = 5 ID = 3 Name = "23" Access = 0 ID = 0 Name = "50" Access = 1 ID = 7 Name = "93" Access = 4 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 0 find ID = 0 Name = "50" size of cache = 5 ID = 3 Name = "23" Access = 0 ID = 0 Name = "50" Access = 2 ID = 7 Name = "93" Access = 4 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 4 size of cache = 5 ID = 4 Name = "10" Access = 0 ID = 0 Name = "50" Access = 2 ID = 7 Name = "93" Access = 4 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 1 size of cache = 5 ID = 1 Name = "76" Access = 0 ID = 0 Name = "50" Access = 2 ID = 7 Name = "93" Access = 4 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 2 size of cache = 5 ID = 2 Name = "29" Access = 0 ID = 0 Name = "50" Access = 2 ID = 7 Name = "93" Access = 4 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 4 size of cache = 5 ID = 4 Name = "48" Access = 0 ID = 0 Name = "50" Access = 2 ID = 7 Name = "93" Access = 4 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 2 size of cache = 5 ID = 2 Name = "79" Access = 0 ID = 0 Name = "50" Access = 2 ID = 7 Name = "93" Access = 4 ID = 6 Name = "24" Access = 4 ID = 5 Name = "7" Access = 3 Request = 6 find ID = 6 Name = "24" size of cache = 5 ID = 2 Name = "79" Access = 0 ID = 0 Name = "50" Access = 2 ID = 7 Name = "93" Access = 4 ID = 6 Name = "24" Access = 5 ID = 5 Name = "7" Access = 3 Request = 0 find ID = 0 Name = "50" size of cache = 5 ID = 2 Name = "79" Access = 0 ID = 0 Name = "50" Access = 3 ID = 7 Name = "93" Access = 4 ID = 6 Name = "24" Access = 5 ID = 5 Name = "7" Access = 3 Request = 7 find ID = 7 Name = "93" size of cache = 5 ID = 2 Name = "79" Access = 0 ID = 0 Name = "50" Access = 3 ID = 7 Name = "93" Access = 5 ID = 6 Name = "24" Access = 5 ID = 5 Name = "7" Access = 3 Request = 5 find ID = 5 Name = "7" size of cache = 5 ID = 2 Name = "79" Access = 0 ID = 0 Name = "50" Access = 3 ID = 7 Name = "93" Access = 5 ID = 6 Name = "24" Access = 5 ID = 5 Name = "7" Access = 4 Request = 2 find ID = 2 Name = "79" size of cache = 5 ID = 2 Name = "79" Access = 1 ID = 0 Name = "50" Access = 3 ID = 7 Name = "93" Access = 5 ID = 6 Name = "24" Access = 5 ID = 5 Name = "7" Access = 4 Request = 9 size of cache = 5 ID = 9 Name = "2" Access = 0 ID = 0 Name = "50" Access = 3 ID = 7 Name = "93" Access = 5 ID = 6 Name = "24" Access = 5 ID = 5 Name = "7" Access = 4 Request = 3 size of cache = 5 ID = 3 Name = "16" Access = 0 ID = 0 Name = "50" Access = 3 ID = 7 Name = "93" Access = 5 ID = 6 Name = "24" Access = 5 ID = 5 Name = "7" Access = 4 Request = 3 find ID = 3 Name = "16" size of cache = 5 ID = 3 Name = "16" Access = 1 ID = 0 Name = "50" Access = 3 ID = 7 Name = "93" Access = 5 ID = 6 Name = "24" Access = 5 ID = 5 Name = "7" Access = 4 Request = 0 find ID = 0 Name = "50" size of cache = 5 ID = 3 Name = "16" Access = 1 ID = 0 Name = "50" Access = 4 ID = 7 Name = "93" Access = 5 ID = 6 Name = "24" Access = 5 ID = 5 Name = "7" Access = 4 Request = 6 find ID = 6 Name = "24" size of cache = 5 ID = 3 Name = "16" Access = 1 ID = 0 Name = "50" Access = 4 ID = 7 Name = "93" Access = 5 ID = 6 Name = "24" Access = 6 ID = 5 Name = "7" Access = 4 Request = 8 size of cache = 5 ID = 8 Name = "85" Access = 0 ID = 0 Name = "50" Access = 4 ID = 7 Name = "93" Access = 5 ID = 6 Name = "24" Access = 6 ID = 5 Name = "7" Access = 4
|