From: Michael Tremer Date: Wed, 22 Oct 2025 20:28:01 +0000 (+0000) Subject: metrics: Only require one allocation X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a47bd6dad0ceb128beb248bf5270e737a4045c5;p=telemetry.git metrics: Only require one allocation Since we know how many metrics we might expect from the beginning we can realise the metrics as a variable array and only have one allocation. Since this application is having a lot of allocations, this would quite save a bit of memory fragmentation and load on the allocator. Signed-off-by: Michael Tremer --- diff --git a/src/daemon/metrics.c b/src/daemon/metrics.c index e61ff68..79e9016 100644 --- a/src/daemon/metrics.c +++ b/src/daemon/metrics.c @@ -65,8 +65,8 @@ struct td_metrics { struct timeval t; // Metrics - td_metric* metrics; unsigned int num_metrics; + td_metric metrics[]; }; static int td_metrics_valid_object(td_metrics* self, const char* object) { @@ -113,17 +113,19 @@ static void td_metrics_free(td_metrics* self) { td_source_unref(self->source); if (self->ctx) td_ctx_unref(self->ctx); - if (self->metrics) - free(self->metrics); free(self); } int td_metrics_create(td_metrics** metrics, td_ctx* ctx, td_source* source, const char* object) { + unsigned int num_metrics = 0; td_metrics* self = NULL; int r; + // Fetch how many data sources there are + num_metrics = td_source_num_data_sources(source); + // Allocate some memory - self = calloc(1, sizeof(*self)); + self = calloc(1, sizeof(*self) + (num_metrics * sizeof(*self->metrics))); if (!self) return -errno; @@ -150,6 +152,9 @@ int td_metrics_create(td_metrics** metrics, td_ctx* ctx, td_source* source, cons } } + // Store the number of data sources + self->num_metrics = num_metrics; + // Fetch the current time r = gettimeofday(&self->t, NULL); if (r < 0) { @@ -157,24 +162,6 @@ int td_metrics_create(td_metrics** metrics, td_ctx* ctx, td_source* source, cons goto ERROR; } - // Fetch the number of data sources - self->num_metrics = td_source_num_data_sources(self->source); - - // Fail if there are no data sources - if (!self->num_metrics) { - ERROR(self->ctx, "Source %s has no data sources\n", td_source_name(self->source)); - r = -EINVAL; - goto ERROR; - } - - // Allocate space for the metrics - self->metrics = calloc(self->num_metrics, sizeof(*self->metrics)); - if (!self->metrics) { - ERROR(self->ctx, "Failed to allocate %u metric(s): %m\n", self->num_metrics); - r = -errno; - goto ERROR; - } - // Return the pointer *metrics = self; return 0;