[gparted] Further improve speed of PipeCapture for non-watched output (#777973)
- From: Curtis Gedak <gedakc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gparted] Further improve speed of PipeCapture for non-watched output (#777973)
- Date: Sat, 3 Jun 2017 15:43:27 +0000 (UTC)
commit 25780c611bf99ce3f819d00c58616fa517a38b0f
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date: Sat Mar 18 15:35:07 2017 +0000
Further improve speed of PipeCapture for non-watched output (#777973)
For large output a lot of time is used copying capturebuf to callerbuf
to provide a Glib::ustring copy of the buffer for the update callback.
However update callbacks are only used when commands are run to apply
operations by FileSystem::execute_command() and their output is
incrementally displayed in the UI. Whereas update callbacks are never
used when commands are used to query information via
Utils::execute_command().
Stop performing interim copying of capturebuf to callerbuf when there
are no update callbacks registered as it is unnecessary.
Time to read portions of the recorded fsck.fat output via
fat16::set_used_sectors() and intermediate copies aren't required:
1 MiB 10 MiB 122 MiB
old code : 0.074 sec 1.41 sec 210 sec [3:30]
new code : 0.063 sec 0.56 sec 6.57 sec
Bug 777973 - Segmentation fault on bad disk
include/PipeCapture.h | 1 +
src/PipeCapture.cc | 30 ++++++++++++++++++++++--------
2 files changed, 23 insertions(+), 8 deletions(-)
---
diff --git a/include/PipeCapture.h b/include/PipeCapture.h
index d986b3f..95fc763 100644
--- a/include/PipeCapture.h
+++ b/include/PipeCapture.h
@@ -55,6 +55,7 @@ private:
std::string capturebuf; // Captured output as UTF-8 characters
size_t line_start; // Index into bytebuf where current line starts
Glib::ustring & callerbuf; // Reference to caller supplied buffer
+ bool callerbuf_uptodate; // Has capturebuf changed since last copied to callerbuf?
};
} // namepace GParted
diff --git a/src/PipeCapture.cc b/src/PipeCapture.cc
index 053c3b2..52e45cc 100644
--- a/src/PipeCapture.cc
+++ b/src/PipeCapture.cc
@@ -37,6 +37,7 @@ PipeCapture::PipeCapture( int fd, Glib::ustring &buffer ) : fill_offset( 0 ),
{
readbuf = new char[READBUF_SIZE];
callerbuf.clear();
+ callerbuf_uptodate = true;
// tie fd to string
// make channel
channel = Glib::IOChannel::create_from_fd( fd );
@@ -95,10 +96,10 @@ bool PipeCapture::OnReadable( Glib::IOCondition condition )
// is drained the partial current line, is pasted into capturebuf at the offset
// where the last line starts. (Capturebuf stores UTF-8 encoded characters in a
// std::string for constant time access to line_start offset). When readbuf
- // is drained capturebuf is copied into callerbuf and signal_update slot fired.
- // (Callerbuf stores UTF-8 encoded characters in a Glib::ustring). When EOF is
- // encountered capturebuf is copied into callerbuf if required and signal_eof slot
- // fired.
+ // is drained and there are registered update callbacks, capturebuf is copied into
+ // callerbuf and signal_update slot fired. (Callerbuf stores UTF-8 encoded
+ // characters in a Glib::ustring). When EOF is encountered capturebuf is copied
+ // into callerbuf if required and signal_eof slot fired.
//
// Golden rule:
// Use Glib::ustrings as little as possible for large amounts of data!
@@ -187,6 +188,7 @@ bool PipeCapture::OnReadable( Glib::IOCondition condition )
capturebuf.resize( line_start );
append_unichar_vector_to_utf8( capturebuf, linevec );
line_start = capturebuf.size();
+ callerbuf_uptodate = false;
linevec.clear();
cursor = 0;
@@ -213,13 +215,20 @@ bool PipeCapture::OnReadable( Glib::IOCondition condition )
}
}
- // Paste partial line to capture buffer; copy that to callers buffer; and
- // fire any update callbacks.
+ // Paste partial line to capture buffer.
capturebuf.resize( line_start );
append_unichar_vector_to_utf8( capturebuf, linevec );
+ callerbuf_uptodate = false;
- callerbuf = capturebuf;
- signal_update.emit();
+ if ( ! signal_update.empty() )
+ {
+ // Performance optimisation, especially for large capture buffers:
+ // only copy capture buffer to callers buffer and fire update
+ // callbacks when there are any registered update callbacks.
+ callerbuf = capturebuf;
+ callerbuf_uptodate = true;
+ signal_update.emit();
+ }
return true;
}
@@ -228,6 +237,11 @@ bool PipeCapture::OnReadable( Glib::IOCondition condition )
std::cerr << "Pipe IOChannel read failed" << std::endl;
}
+ if ( ! callerbuf_uptodate )
+ {
+ callerbuf = capturebuf;
+ callerbuf_uptodate = true;
+ }
// signal completion
signal_eof.emit();
return false;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]