properties: Skip value building for nominal case
bus_message_print_all_properties() builds a PROP= string for every
property in the reply so that -p PROP=value filters can be matched
against it, but most queries never need this.
Take the normal `systemctl show` or `systemctl show UNIT` case. In that
case there is no filter. Even with `-p PROP` there is no value filter
since there is no value.
Avoid constructing the string entirely by comparing property names
directly against filter entries.
In my tests with a `systemctl show` over 160 units this brings the
instructions retired from 992.6M down to 960.5M, a reduction of 3.2%.
The same goes for property filters with units. When running:
systemctl show -p UnitFileState -p ActiveState UNIT
...the instructions retired drops from 9.52M to 9.22M, a reduction of
3.2%. The output in each case is unchanged.
This commit is contained in:
@@ -344,6 +344,34 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool match_filter(char **filter, const char *name, const char **ret_expected_value) {
|
||||
const char *expected_value = NULL;
|
||||
|
||||
assert(name);
|
||||
assert(ret_expected_value);
|
||||
|
||||
if (!filter) {
|
||||
*ret_expected_value = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
STRV_FOREACH(f, filter) {
|
||||
const char *p = startswith(*f, name);
|
||||
|
||||
if (!p)
|
||||
continue;
|
||||
if (*p == '\0') {
|
||||
*ret_expected_value = NULL;
|
||||
return true;
|
||||
}
|
||||
if (*p == '=' && !expected_value)
|
||||
expected_value = p + 1;
|
||||
}
|
||||
|
||||
*ret_expected_value = expected_value;
|
||||
return expected_value != NULL;
|
||||
}
|
||||
|
||||
int bus_message_print_all_properties(
|
||||
sd_bus_message *m,
|
||||
bus_message_print_t func,
|
||||
@@ -360,7 +388,6 @@ int bus_message_print_all_properties(
|
||||
return r;
|
||||
|
||||
while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
|
||||
_cleanup_free_ char *name_with_equal = NULL;
|
||||
const char *name, *contents, *expected_value = NULL;
|
||||
|
||||
r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &name);
|
||||
@@ -373,14 +400,7 @@ int bus_message_print_all_properties(
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
name_with_equal = strjoin(name, "=");
|
||||
if (!name_with_equal)
|
||||
return log_oom();
|
||||
|
||||
if (!filter ||
|
||||
strv_contains(filter, name) ||
|
||||
(expected_value = strv_find_startswith(filter, name_with_equal))) {
|
||||
|
||||
if (match_filter(filter, name, &expected_value)) {
|
||||
r = sd_bus_message_peek_type(m, NULL, &contents);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user