From 51ade2f1dbf12873d1f56b8d49c75dfe6b2cb34a Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 15 Sep 2024 12:40:25 +0200 Subject: [PATCH] OPTIM: sample: don't check casts for samples of same type Originally when converters were created, they were mostly for casting types. Nowadays we have many artithmetic converters to perform operations on integers, and a number of converters operating on strings. Both of these categories most often do not need any cast since the input and output types are the same, which is visible as the cast function is c_none. However, profiling shows that when heavily using arithmetic converters, it's possible to spend up to ~7% of the time in sample_process_cnv(), a good part of which is only in accessing the sample_casts[] array. Simply avoiding this lookup when input and ouput types are equal saves about 2% CPU on such setups doing intensive use of converters. --- src/sample.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/sample.c b/src/sample.c index 61d51fa36..087367da3 100644 --- a/src/sample.c +++ b/src/sample.c @@ -1318,12 +1318,14 @@ int sample_process_cnv(struct sample_expr *expr, struct sample *p) * - c_none => nothing to do (let's optimize it) * - other => apply cast and prepare to fail */ - if (!sample_casts[p->data.type][conv_expr->conv->in_type]) - return 0; + if (p->data.type != conv_expr->conv->in_type) { + if (!sample_casts[p->data.type][conv_expr->conv->in_type]) + return 0; - if (sample_casts[p->data.type][conv_expr->conv->in_type] != c_none && - !sample_casts[p->data.type][conv_expr->conv->in_type](p)) - return 0; + if (sample_casts[p->data.type][conv_expr->conv->in_type] != c_none && + !sample_casts[p->data.type][conv_expr->conv->in_type](p)) + return 0; + } /* OK cast succeeded */ @@ -1690,12 +1692,14 @@ struct sample *sample_fetch_as_type(struct proxy *px, struct session *sess, return NULL; } - if (!sample_casts[smp->data.type][smp_type]) - return NULL; + if (smp->data.type != smp_type) { + if (!sample_casts[smp->data.type][smp_type]) + return NULL; - if (sample_casts[smp->data.type][smp_type] != c_none && - !sample_casts[smp->data.type][smp_type](smp)) - return NULL; + if (sample_casts[smp->data.type][smp_type] != c_none && + !sample_casts[smp->data.type][smp_type](smp)) + return NULL; + } smp->flags &= ~SMP_F_MAY_CHANGE; return smp;