From 3d2dcd7b53979a1050ad632ac4881c2a7dd618af Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Sat, 1 Oct 2016 21:22:12 +0200 Subject: [PATCH] write_prometheus plugin: Improve performance of metric_cmp(). This function is a hotspot because it is used by bsearch() to look up metrics in a metric family. This simple (though non-obvious) change brings prom_write() complexity down from 3000 instructions/call to 2640 instructions/call, i.e. a 12% improvement. --- src/write_prometheus.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/write_prometheus.c b/src/write_prometheus.c index 4a9761a0..6c882781 100644 --- a/src/write_prometheus.c +++ b/src/write_prometheus.c @@ -297,17 +297,37 @@ static int metric_cmp(void const *a, void const *b) { return 1; /* Prometheus does not care about the order of labels. All labels in this - * plugin are created by metric_add_labels(), though, and therefore always + * plugin are created by METRIC_ADD_LABELS(), though, and therefore always * appear in the same order. We take advantage of this and simplify the check - * by making sure all labels are the same in each position. */ + * by making sure all labels are the same in each position. + * + * We also only need to check the label values, because the label names are + * the same for all metrics in a metric family. + * + * 3 labels: + * [0] $plugin="$plugin_instance" => $plugin is the same within a family + * [1] type="$type_instance" => "type" is a static string + * [2] instance="$host" => "instance" is a static string + * + * 2 labels, variant 1: + * [0] $plugin="$plugin_instance" => $plugin is the same within a family + * [1] instance="$host" => "instance" is a static string + * + * 2 labels, variant 2: + * [0] $plugin="$type_instance" => $plugin is the same within a family + * [1] instance="$host" => "instance" is a static string + * + * 1 label: + * [1] instance="$host" => "instance" is a static string + */ for (size_t i = 0; i < m_a->n_label; i++) { - int status = strcmp(m_a->label[i]->name, m_b->label[i]->name); + int status = strcmp(m_a->label[i]->value, m_b->label[i]->value); if (status != 0) return status; - status = strcmp(m_a->label[i]->value, m_b->label[i]->value); - if (status != 0) - return status; +#if COLLECT_DEBUG + assert(strcmp(m_a->label[i]->name, m_b->label[i]->name) == 0); +#endif } return 0; -- 2.11.0