android_system_core/logcat/tests/logcat_benchmark.cpp
Mark Salyzyn 71919f4f5d liblogcat: measure performance
Existing dummy benchmark converted to a single-pass benchmark.

Add support for ">[filename]" interpretation in liblogcat, helpful to
provide more consistent benchmark results when sending output to
/dev/null.

NB: results are not consistent as there is a roundtrip to logd
    service, but they are indicative of better performance for
    liblogcat.

Benchmark                                Time           CPU Iterations
----------------------------------------------------------------------
BM_logcat_stat_popen_libc         35221677 ns     603314 ns        100
BM_logcat_stat_popen_liblogcat    15871805 ns     579398 ns       1287
BM_logcat_stat_system_libc        39037825 ns     319882 ns        100
BM_logcat_stat_system_liblogcat    9896755 ns     762610 ns       1310
BM_logcat_dump_popen_libc        776206254 ns  131448772 ns          5
BM_logcat_dump_popen_liblogcat   610674905 ns  118709624 ns          6
BM_logcat_dump_system_libc       512191254 ns     388724 ns         10
BM_logcat_dump_system_liblogcat  443897570 ns  377215696 ns          2

Test: logcat-benchmarks --benchmark_filter='BM_logcat_stat*|BM_logcat_dump*'
Bug: 35326290
Change-Id: Ie94900a3070487f45742f6c0789b5b3cf036df34
2017-02-22 16:06:24 -08:00

133 lines
3.6 KiB
C++

/*
* Copyright (C) 2013-2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <benchmark/benchmark.h>
static const char begin[] = "--------- beginning of ";
static void BM_logcat_sorted_order(benchmark::State& state) {
FILE* fp;
if (!state.KeepRunning()) return;
fp = popen(
"logcat -v time -b radio -b events -b system -b main -d 2>/dev/null",
"r");
if (!fp) return;
class timestamp {
private:
int month;
int day;
int hour;
int minute;
int second;
int millisecond;
bool ok;
public:
void init(const char* buffer) {
ok = false;
if (buffer != NULL) {
ok = sscanf(buffer, "%d-%d %d:%d:%d.%d ", &month, &day, &hour,
&minute, &second, &millisecond) == 6;
}
}
explicit timestamp(const char* buffer) {
init(buffer);
}
bool operator<(timestamp& T) {
return !ok || !T.ok || (month < T.month) ||
((month == T.month) &&
((day < T.day) ||
((day == T.day) &&
((hour < T.hour) ||
((hour == T.hour) &&
((minute < T.minute) ||
((minute == T.minute) &&
((second < T.second) ||
((second == T.second) &&
(millisecond < T.millisecond))))))))));
}
bool valid(void) {
return ok;
}
} last(NULL);
char* last_buffer = NULL;
char buffer[5120];
int count = 0;
int next_lt_last = 0;
while (fgets(buffer, sizeof(buffer), fp)) {
if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
continue;
}
if (!last.valid()) {
free(last_buffer);
last_buffer = strdup(buffer);
last.init(buffer);
}
timestamp next(buffer);
if (next < last) {
if (last_buffer) {
fprintf(stderr, "<%s", last_buffer);
}
fprintf(stderr, ">%s", buffer);
++next_lt_last;
}
if (next.valid()) {
free(last_buffer);
last_buffer = strdup(buffer);
last.init(buffer);
}
++count;
}
free(last_buffer);
pclose(fp);
static const int max_ok = 2;
// Allow few fails, happens with readers active
fprintf(stderr, "%s: %d/%d out of order entries\n",
(next_lt_last) ? ((next_lt_last <= max_ok) ? "WARNING" : "ERROR")
: "INFO",
next_lt_last, count);
if (next_lt_last > max_ok) {
fprintf(stderr, "EXPECT_GE(max_ok=%d, next_lt_last=%d)\n", max_ok,
next_lt_last);
}
// sample statistically too small
if (count < 100) {
fprintf(stderr, "EXPECT_LT(100, count=%d)\n", count);
}
state.KeepRunning();
}
BENCHMARK(BM_logcat_sorted_order);
BENCHMARK_MAIN();