簡體   English   中英

可靠地使用C ++小字符串優化將短std :: string從文件中讀取到內存中

[英]Reliably using C++ Small String Optimization to fread short std::strings from Files into Memory

我有以下類,它包含一個稱為Index的數據結構,它的計算成本很高。 因此,我將索引緩存到磁盤並再次讀入。 模板類型T的索引元素id可以與各種原始數據類型一起使用。

但我也想將id與std :: string類型一起使用。 我為一般情況編寫了序列化/反序列化代碼,並且還測試了它是否適用於普通的C ++字符串,並且是否足夠短(如果它們足夠短的話)。 小字符串優化似乎開始了。

我還寫了一個不同的實現,只是為了安全地處理更長的字符串。 但是安全代碼的速度慢了大約10倍,我真的很想讀入帶有fread的字符串(500ms的讀取非常痛苦,而50ms的情況則非常好)。

如果我知道所有標識符都比最長的短字符串短,那么如何可靠地使用libcpp小字符串優化? 如何可靠地確定最長的小字符串有多長時間?

template<typename T>
class Reader {
public:
    struct Index {
        T id;
        size_t length;
        // ... values etc
    };

    Index* index;
    size_t indexTableSize;

    void serialize(const char* fileName) {
        FILE *file = fopen(fileName, "w+b");
        if (file == NULL)
            return;

        fwrite(&indexTableSize, sizeof(size_t), 1, file);
        fwrite(index, sizeof(Index), indexTableSize, file);

        fclose(file);
    }

    void deserialize(const char* fileName) {
        FILE *file = fopen(fileName, "rb");
        if (file == NULL)
            return;

        fread(&indexTableSize, sizeof(size_t), 1, file);
        index = new Index[indexTableSize];
        fread(index, sizeof(Index), indexTableSize, file);

        fclose(file);
    }


};

// works perfectly fine
template class Reader<int32_t>;

// works perfectly fine for strings shorter than 22 bytes
template class Reader<std::string>;

std::string是不可復制的 並執行memcpy上的類型(這是相當於fwrite荷蘭國際集團它和fread在C ++荷蘭國際集團回)是唯一的合法,如果它是平凡能夠復制。 因此,您想做的事情無法直接實現。

如果要序列化字符串,則必須手動進行。 您必須先獲取字符數並將其寫入,然后再自己寫這些字符。 要讀回它,您必須讀取字符串的大小,然后讀取那么多字符。

如果要使用類型T可靠地進行序列化/反序列化,則必須確保類型T是POD類型(或更准確地說是標准布局瑣碎的 )。

您可以使用std::is_trivially_copyable<T>std::is_standard_layout<T>在模板中進行檢查。 不幸的是,這對於std::string將失敗。

如果不是這種情況,則必須找到一種適當的方法來對類進行序列化/反序列化,即,寫入/讀取允許重建對象狀態的數據(此處為字符串的長度及其內容)。

三種選擇:

  • 使用一個輔助模板,該輔助模板將T從字節數組轉換為字節數組,並為可能用於您的Reader的每種類型編寫此模板的特殊化說明。
  • 使用執行此操作的成員函數。 但這對於std類型是不可能的。
  • 使用序列化庫,例如boost::serializes11n其他

無論如何,我都強烈建議您不要依賴非可移植屬性 ,例如短字符串的長度,尤其是如果您的模板中的代碼應與泛型類型一起使用時,尤其如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM