[英]C++ Binary File I/O Operations Slow Down... How DB Handle Binary Files?
我正在嘗試制作一個簡單的基於文件的哈希表。 這是我的insert
成員函數:
private: std::fstream f; // std::ios::in | std::ios::out | std::ios::binary
public: void insert(const char* this_key, long this_value) {
char* that_key;
long that_value;
long this_hash = std::hash<std::string>{}(this_key) % M;
long that_hash; // also block status
long block = this_hash;
long offset = block * BLOCK_SIZE;
while (true) {
this->f.seekg(offset);
this->f.read((char*) &that_hash, sizeof(long));
if (that_hash > -1) { // -1 (by default) indicates a never allocated block
this->f.read(that_key, BLOCK_SIZE);
if (strcmp(this_key, that_key) == 0) {
this->f.seekp(this->f.tellg());
this->f.write((char*) &this_value, sizeof(long));
break;
} else {
block = (block + 1) % M; // linear probing
offset = block * BLOCK_SIZE;
continue;
}
} else {
this->f.seekp(offset);
this->f.write((char*) &this_hash, sizeof(long)); // as block status
this->f.write(this_key, KEY_SIZE);
this->f.write((char*) &this_value, sizeof(long));
break;
}
}
}
測試多達 10M 的鍵值對,包含 50,000,017 個塊,結果相當不錯。 (二進制文件大小約為 3.8GB)。
但是,使用 50M 密鑰和 250,000,013 個塊進行的測試非常慢......(在這種情況下,二進制文件大小超過 19GB)。 1,000 insert
s通常需要4~5ms,但特別需要2,000ms以上。 它變得越來越慢,然后需要 40~150 毫秒......(x10 ~ x30 慢......)我絕對不知道......
seekg
& seekp
等 I/O 操作是否受文件大小影響? (雖然我找不到關於這個問題的任何參考資料......)數據大小
通常磁盤驅動器塊大小是 2 的冪,所以如果您的數據塊大小也是 2 的冪,那么您基本上可以消除數據塊跨越磁盤塊邊界的情況。
在您的情況下,64 字節的值(如果您真的不需要存儲散列,則為 32 字節)可能會表現得更好一些。
廣告訂單
你可以做的另一件事是提高性能,你的插入是增加哈希順序,以減少必須從磁盤加載數據的時間。
一般在磁盤讀寫數據時,OS會一次讀寫一個大chuck(可能4k),所以如果你寫的算法是一種及時在本地寫入數據的方式,你會減少次數數據必須實際讀取或寫入磁盤。
鑒於您進行了大量插入,一種可能性是一次批量處理插入,例如 1000 個甚至 10000 個鍵/值對。 本質上,您將在內存中累積數據並對其進行排序,一旦您有足夠的項目(或完成插入),您將按順序寫入數據。
這樣,您應該能夠減少非常緩慢的磁盤訪問。 如果您使用傳統硬盤驅動器,這可能更重要,因為移動磁頭很慢(在這種情況下,對其進行碎片整理可能很有用)。 另外,請確保您的硬盤驅動器有足夠的可用空間。
在某些情況下,本地緩存(在您的應用程序中)也可能會有所幫助,特別是如果您知道如何使用您的數據。
文件大小 VS 沖突
當您使用散列時,您希望找到文件大小和沖突之間的最佳位置。 如果您有太多的碰撞,那么您將浪費大量時間,並且在某些時候它可能會退化,因為幾乎每次插入都很難找到空閑位置。
另一方面,如果您的文件確實非常大,您最終可能會遇到這樣一種情況:您可能會用主要為空的數據填充 RAM,並且在幾乎所有插入時仍需要用磁盤中的數據替換數據。
例如,如果您的數據是 20GB,並且您可以在內存中加載 2GB,那么如果插入真的是隨機的,那么 90% 的時間您可能需要真正訪問硬盤。
配置
好選項將取決於操作系統,它超出了編程論壇的范圍。 如果您想優化您的計算機,那么您應該尋找其他地方。
讀
閱讀有關操作系統(文件系統、緩存層……)和算法(外部排序算法、B 樹和其他結構)以更好地理解可能會有所幫助。
備擇方案
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.