2016-08-06 5 views
-4

私はファイルからstd::wstringに非常に大きなXMLファイルをロードする必要があるC++プロジェクト(VS2008を使用しています)に取り組んでいます。std :: stringのサイズを変更する最も速い方法は何ですか?

//std::wstring str; 
//size_t ncbDataSz = file size in bytes 

str.resize(ncbDataSz/sizeof(WCHAR)); 

をしかし、私の現在の問題はresize方法は、(私はちょうどx64で、データの3ギガバイトとそれをテストし、より大きな文字列サイズのため、多少時間がかかることである。現在、データがロードされる前に、次の行には、メモリを確保しプロジェクト、デスクトップPCで12GBの空きRAMがあり、完了に約4〜5秒かかった)

std::stringのサイズを変更する高速化された(最適化された)方法がありますか?私はWindowsのみを求めています。

+3

'std :: string :: reserve'は' std :: string :: resize'を予約します。 IMを上書きするmediate、私は思います。 – LogicStuff

+0

サイズを変更するか予約しますか? – user463035818

+0

@LogicStuff: '予約'は奇妙な獣です。それはメモリを "予約"しますが、それを連続したバイト配列として直接アクセスすることはできません。私はそれに 'append'を呼び出す必要があります。その場合、このタイプの最適化は私には役に立たない。 – c00000fd

答えて

1

入力文字列のサイズを変更する代わりに、std::string::reserveを使用して割り当てることができます。サイズ変更では、すべての要素も初期化されるためです。

あなたはそれがあなたのためにパフォーマンスが改善されるかどうかを確認するために、このような何かを試みることができる:

std::wstring load_file(std::string const& filename) 
{ 
    std::wifstream ifs(filename, std::ios::ate); 

    // errno works on POSIX systems not sure about windows 
    if(!ifs) 
     throw std::runtime_error(std::strerror(errno)); 

    std::wstring s; 
    s.reserve(ifs.tellg()); // allocate but don't initialize 
    ifs.seekg(0); 

    wchar_t buf[4096]; 
    while(ifs.read(buf, sizeof(buf)/sizeof(buf[0]))) 
     s.append(buf, buf + ifs.gcount()); // this will never reallocate 

    return s; 
} 
+0

ありがとうございます。しかし、あなたがしているのは、 's.reserve'と' wchar_t buf'という2つのバッファをあらかじめ割り当てているところです。ですから、 's.reserve'を実行した後、どうすれば直接ロードできますか?または 'ReadFile(hFile、&s [0]、sz、szRead、NULL);'サイズを調整する必要があります。しかしどうですか? – c00000fd

+0

@ c00000fd予約メモリに読み込めません。しかし、buf [4096]の割り当ては、高速化しているスタック上にあります(1命令?)。一日の終わりには、測定が速ければ速いかどうかだけを知ることができます。 – Galik

+0

私はGBのデータについて話しているので、スタックは問題外です。そしてファイルから小さなまとまりに読み込むことは、 'resize'を使わないことよりもさらに遅くなります。 – c00000fd

1

、割り当てるに何もしないchar_traitsでのbasic_stringインスタンス化することができます(カウント):

#include <string> 

struct noinit_char_traits : std::char_traits<char> { 
    using std::char_traits<char>::assign; 
    static char_type* assign(char_type* p, std::size_t count, char_type a) { return p; } 
}; 

using noinit_string = std::basic_string<char, noinit_char_traits>; 

に留意されたいです。また、basic_string :: fill()などの関数にも影響します。

関連する問題