2010-11-04 20 views
1

我必須讀入一個巨大的文本文件(> 200,000字)並處理每個單詞。我將整個文件讀入一個字符串,然後附加一個字符串流以便輕鬆處理每個單詞。方法是我直接從文件中使用<<輸入每個單詞並對其進行處理,但比較這兩種方法在執行時間方面沒有任何優勢。對內存中的字符串操作不是比每次需要單詞時需要系統調用的文件更快嗎?請提出一些提高性能的方法。C++中字符串流與文件I/O流的性能

+0

流做一些內部的緩衝。擺弄緩衝區大小以找到最佳配合。 – codymanix 2010-11-04 17:52:09

+0

查看@Martin約克的答案在這裏爲'從文件'stringstream,最大限度地減少複製 - http://stackoverflow.com/questions/132358/how-to-read-file-content-into-istringstream – 2010-11-04 17:58:26

+0

我正要建議。 – 2010-11-04 18:01:39

回答

1

有涉及的緩存,所以它不一定每次你提取系統調用。話雖如此,通過解析單個連續的緩衝區,您在解析時可能會獲得稍好的性能。另一方面,您正在序列化工作負載(讀取整個文件,然後解析),這可能會被並行化(並行讀取和解析)。

1

該字符串將重新分配和複製很多次,以容納200,000字。這可能是花時間。

如果你想通過追加來創建一個巨大的字符串,你應該使用一根繩子。

+1

如果您提出修復建議,這可能會成爲一個很好的答案。 – 2010-11-04 17:54:51

4

如果你打算把數據放到一個字符串流,無論如何,它可能是一個更快一點,更容易直接從輸入流複製到字符串流:

std::ifstream infile("yourfile.txt"); 
std::stringstream buffer; 

buffer << infile.rdbuf(); 

ifstream將使用一個緩衝但是,雖然這可能比讀入字符串更快,然後創建一個字符串流,但它可能不會比直接從輸入流中處理更快。

+3

如果還有其他I/O與此處理並行發生,則數據的一次加載將會更可取,因爲磁盤頭在緩衝區刷新之間沒有相同的機會。 – 2010-11-04 18:01:36

+0

@Steve:我沒有想到這一點,但這是一個很好的觀點。 – 2010-11-04 18:34:27

+0

我認爲這與Martin對前q的回答結合起來表現最好。我給了你+1最好的本地信息 – 2010-11-04 18:35:11

4

出於性能和最小的複製,這是很難被擊敗(只要你有足夠的內存!):

void mapped(const char* fname) 
{ 
    using namespace boost::interprocess; 

    //Create a file mapping 
    file_mapping m_file(fname, read_only); 

    //Map the whole file with read permissions 
    mapped_region region(m_file, read_only); 

    //Get the address of the mapped region 
    void * addr  = region.get_address(); 
    std::size_t size = region.get_size(); 

    // Now you have the underlying data... 
    char *data = static_cast<char*>(addr); 

    std::stringstream localStream; 
    localStream.rdbuf()->pubsetbuf(data, size); 

    // now you can do your stuff with the stream 
    // alternatively 
}