、あなたは入出力ストリームを使用している場合はstd::endl
を使用してではなく、代わりに'\n'
を使用してないにより、例えば、誤ってストリームをフラッシュする回避しようとする場合があります。 IOStreamsへの書き込みはバッファリングされているので、パフォーマンスがかなり向上する可能性があります。
これで十分でない場合、次の質問はデータの書き方です。多くの書式設定が行われている場合は、実際の書式設定にほとんど時間がかかる可能性があります。書式を別のスレッドにプッシュすることができるかもしれませんが、それは単純に2バイトを別のスレッドに渡すこととは全く異なります。フォーマットするデータを保持する適切なデータ構造を渡す必要があります。あなたが実際に何を書いているかによって、適切なものが決まります。
最後に、バッファをファイルに書き込むことが実際にボトルネックで、標準のC++ライブラリを利用したい場合は、適切なストリームバッファからバッファで満たされたキューをリッスンするライタースレッドを持つのが妥当かもしれませんstd::ofstream
にバッファを書き込みます。プロデューサインターフェイスはstd::ostream
になります。バッファがいっぱいになったり、ストリームがフラッシュされたときに(おそらく、std::flush
を明示的に使用して)キューに固定サイズのバッファを送ります。もう一方の読書は聞きます。以下は、標準ライブラリの機能を使用して、そのアイデアの迅速な実装です:
#include <condition_variable>
#include <fstream>
#include <mutex>
#include <queue>
#include <streambuf>
#include <string>
#include <thread>
#include <vector>
struct async_buf
: std::streambuf
{
std::ofstream out;
std::mutex mutex;
std::condition_variable condition;
std::queue<std::vector<char>> queue;
std::vector<char> buffer;
bool done;
std::thread thread;
void worker() {
bool local_done(false);
std::vector<char> buf;
while (!local_done) {
{
std::unique_lock<std::mutex> guard(this->mutex);
this->condition.wait(guard,
[this](){ return !this->queue.empty()
|| this->done; });
if (!this->queue.empty()) {
buf.swap(queue.front());
queue.pop();
}
local_done = this->queue.empty() && this->done;
}
if (!buf.empty()) {
out.write(buf.data(), std::streamsize(buf.size()));
buf.clear();
}
}
out.flush();
}
public:
async_buf(std::string const& name)
: out(name)
, buffer(128)
, done(false)
, thread(&async_buf::worker, this) {
this->setp(this->buffer.data(),
this->buffer.data() + this->buffer.size() - 1);
}
~async_buf() {
std::unique_lock<std::mutex>(this->mutex), (this->done = true);
this->condition.notify_one();
this->thread.join();
}
int overflow(int c) {
if (c != std::char_traits<char>::eof()) {
*this->pptr() = std::char_traits<char>::to_char_type(c);
this->pbump(1);
}
return this->sync() != -1
? std::char_traits<char>::not_eof(c): std::char_traits<char>::eof();
}
int sync() {
if (this->pbase() != this->pptr()) {
this->buffer.resize(std::size_t(this->pptr() - this->pbase()));
{
std::unique_lock<std::mutex> guard(this->mutex);
this->queue.push(std::move(this->buffer));
}
this->condition.notify_one();
this->buffer = std::vector<char>(128);
this->setp(this->buffer.data(),
this->buffer.data() + this->buffer.size() - 1);
}
return 0;
}
};
int main()
{
async_buf sbuf("async.out");
std::ostream astream(&sbuf);
std::ifstream in("async_stream.cpp");
for (std::string line; std::getline(in, line);) {
astream << line << '\n' << std::flush;
}
}
それは標準ライブラリの一部ではないのですが、あなた場合は、[libuv](https://github.com/joyent/libuv)チェックアウトする必要があり最高のライブラリソリューションを好きにならないでください – tay10r
@TaylorFlores:ありがとう!私はそれを見ていきますが、最初の赤面では、必要以上に多く見えます。 –
現在、どの機能を読み書きに使用していますか?バッファされたI/Oを実行するstdioライブラリをまだ使用していない場合は、それを試してみてください。もしそうであれば、setvbufを呼び出してバッファサイズを増やすことができます。 – Eric