[vte] parser: cat: Add benchmark mode
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] parser: cat: Add benchmark mode
- Date: Tue, 27 Mar 2018 17:42:02 +0000 (UTC)
commit 02bb51a508a8d368f529ee031cc47db5ba9d599b
Author: Christian Persch <chpe src gnome org>
Date: Tue Mar 27 19:40:12 2018 +0200
parser: cat: Add benchmark mode
Add benchmark mode and repeat counter to parser-cat.
This is useful to measure the time spent in the parser only.
src/parser-cat.cc | 97 +++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 87 insertions(+), 10 deletions(-)
---
diff --git a/src/parser-cat.cc b/src/parser-cat.cc
index ef72900..88319a6 100644
--- a/src/parser-cat.cc
+++ b/src/parser-cat.cc
@@ -258,12 +258,14 @@ printout(GString* str)
static gsize seq_stats[VTE_SEQ_N];
static gsize cmd_stats[VTE_CMD_N];
+static GArray* bench_times;
static void
process_file(int fd,
char const* charset,
bool codepoints,
- bool plain)
+ bool plain,
+ bool quiet)
{
struct vte_parser *parser;
if (vte_parser_new(&parser) != 0)
@@ -276,6 +278,8 @@ process_file(int fd,
auto unichars = g_array_new(FALSE, FALSE, sizeof(gunichar));
auto outbuf = g_string_sized_new(buf_size);
+ auto start_time = g_get_monotonic_time();
+
gsize buf_start = 0;
for (;;) {
auto len = read(fd, buf + buf_start, buf_size - buf_start);
@@ -304,7 +308,7 @@ process_file(int fd,
auto ret = vte_parser_feed(parser,
&seq,
wbuf[i]);
- if (ret < 0) {
+ if (G_UNLIKELY(ret < 0)) {
g_printerr("Parser error!\n");
goto out;
}
@@ -312,15 +316,22 @@ process_file(int fd,
seq_stats[ret]++;
if (ret != VTE_SEQ_NONE) {
cmd_stats[seq->command]++;
- print_seq(outbuf, seq, codepoints, plain);
- if (seq->command == VTE_CMD_LF)
- printout(outbuf);
+ if (!quiet) {
+ print_seq(outbuf, seq, codepoints, plain);
+ if (seq->command == VTE_CMD_LF)
+ printout(outbuf);
+ }
}
}
}
out:
- printout(outbuf);
+ if (!quiet)
+ printout(outbuf);
+
+ int64_t time_spent = g_get_monotonic_time() - start_time;
+ g_array_append_val(bench_times, time_spent);
+
g_string_free(outbuf, TRUE);
g_array_free(unichars, TRUE);
g_free(buf);
@@ -328,22 +339,56 @@ process_file(int fd,
_vte_iso2022_state_free(subst);
}
+static bool
+process_file(int fd,
+ char const* charset,
+ bool codepoints,
+ bool plain,
+ bool quiet,
+ int repeat)
+{
+ if (fd == STDIN_FILENO && repeat != 1) {
+ g_printerr("Cannot consume STDIN more than once\n");
+ return false;
+ }
+
+ for (auto i = 0; i < repeat; ++i) {
+ if (i > 0 && lseek(fd, 0, SEEK_SET) != 0) {
+ g_printerr("Failed to seek: %m\n");
+ return false;
+ }
+
+ process_file(fd, charset, codepoints, plain, quiet);
+ }
+
+ return true;
+}
+
int
main(int argc,
char *argv[])
{
- char* charset = nullptr;
+ gboolean benchmark = false;
gboolean codepoints = false;
gboolean plain = false;
+ gboolean quiet = false;
gboolean statistics = false;
+ int repeat = 1;
+ char* charset = nullptr;
char** filenames = nullptr;
GOptionEntry const entries[] = {
+ { "benchmark", 'b', 0, G_OPTION_ARG_NONE, &benchmark,
+ "Measure time spent parsing each file", nullptr },
{ "charset", 'c', 0, G_OPTION_ARG_STRING, &charset,
"Charset to use (default: UTF-8)", "CHARSET" },
{ "codepoints", 'u', 0, G_OPTION_ARG_NONE, &codepoints,
"Output unicode code points by number", nullptr },
{ "plain", 'p', 0, G_OPTION_ARG_NONE, &plain,
"Output plain text without attributes", nullptr },
+ { "quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet,
+ "Suppress output except for statistics and benchmark", nullptr },
+ { "repeat", 'r', 0, G_OPTION_ARG_INT, &repeat,
+ "Repeat each file COUNT times", "COUNT" },
{ "statistics", 's', 0, G_OPTION_ARG_NONE, &statistics,
"Output statistics", nullptr },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames,
@@ -368,8 +413,11 @@ main(int argc,
return EXIT_FAILURE;
}
+ int exit_status = EXIT_FAILURE;
+
memset(&seq_stats, 0, sizeof(seq_stats));
memset(&cmd_stats, 0, sizeof(cmd_stats));
+ bench_times = g_array_new(false, true, sizeof(int64_t));
if (filenames != nullptr) {
for (auto i = 0; filenames[i] != nullptr; i++) {
@@ -385,14 +433,18 @@ main(int argc,
}
}
if (fd != -1) {
- process_file(fd, charset, codepoints, plain);
+ bool r = process_file(fd, charset, codepoints, plain, quiet, repeat);
close(fd);
+ if (!r)
+ break;
}
}
g_strfreev(filenames);
+ exit_status = EXIT_SUCCESS;
} else {
- process_file(STDIN_FILENO, charset, codepoints, plain);
+ if (process_file(STDIN_FILENO, charset, codepoints, plain, quiet, repeat))
+ exit_status = EXIT_SUCCESS;
}
g_free(charset);
@@ -410,5 +462,30 @@ main(int argc,
}
}
- return 0;
+ if (benchmark) {
+ g_array_sort(bench_times,
+ [](void const* p1, void const* p2) -> int {
+ int64_t const t1 = *(int64_t const*)p1;
+ int64_t const t2 = *(int64_t const*)p2;
+ return t1 == t2 ? 0 : (t1 < t2 ? -1 : 1);
+ });
+
+ int64_t total_time = 0;
+ for (unsigned int i = 0; i < bench_times->len; ++i)
+ total_time += g_array_index(bench_times, int64_t, i);
+
+ g_printerr("\nTimes: best %\'" G_GINT64_FORMAT "µs "
+ "worst %\'" G_GINT64_FORMAT "µs "
+ "average %\'" G_GINT64_FORMAT "µs\n",
+ g_array_index(bench_times, int64_t, 0),
+ g_array_index(bench_times, int64_t, bench_times->len - 1),
+ total_time / (int64_t)bench_times->len);
+ for (unsigned int i = 0; i < bench_times->len; ++i)
+ g_printerr(" %\'" G_GINT64_FORMAT "µs\n",
+ g_array_index(bench_times, int64_t, i));
+ }
+
+ g_array_free(bench_times,true);
+
+ return exit_status;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]