]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
OPTIM: pattern: only apply LRU cache for large enough lists
authorWilly Tarreau <w@1wt.eu>
Sun, 3 Nov 2024 17:42:26 +0000 (18:42 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 15 Nov 2024 14:33:04 +0000 (15:33 +0100)
As shown in issue #1518, the LRU cache has a non-null cost that can
sometimes be above the match cost it's trying to avoid. After a number
of tests, it appears that:
  - "simple" match operations (sub, beg, end, int etc) reach a break-even
    after ~20 patterns in list
  - "heavy" match operations (reg) reach a break-even after ~5 patterns in
    list

Let's only consult the LRU cache when the number of patterns in the
expression is at least as large as this limit. Of course there will
always be outliers but it already starts good.

Another improvement consists in reducing the cache size to further
speed up lookups, which makes sense if less expressions use the cache.

src/pattern.c

index 772628677e80265de1d815394095490ef9a41ff7..98b2b3d1d7ca935941b68c05f95ab11015950c0c 100644 (file)
@@ -496,7 +496,7 @@ struct pattern *pat_match_str(struct sample *smp, struct pattern_expr *expr, int
        }
 
        /* look in the list */
-       if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns)) {
+       if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns) && expr->ref->entry_cnt >= 20) {
                unsigned long long seed = pat_lru_seed ^ (long)expr;
 
                lru = lru64_get(XXH3(smp->data.u.str.area, smp->data.u.str.data, seed),
@@ -539,7 +539,7 @@ struct pattern *pat_match_bin(struct sample *smp, struct pattern_expr *expr, int
        struct pattern *ret = NULL;
        struct lru64 *lru = NULL;
 
-       if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns)) {
+       if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns) && expr->ref->entry_cnt >= 20) {
                unsigned long long seed = pat_lru_seed ^ (long)expr;
 
                lru = lru64_get(XXH3(smp->data.u.str.area, smp->data.u.str.data, seed),
@@ -608,7 +608,7 @@ struct pattern *pat_match_reg(struct sample *smp, struct pattern_expr *expr, int
        struct pattern *ret = NULL;
        struct lru64 *lru = NULL;
 
-       if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns)) {
+       if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns) && expr->ref->entry_cnt >= 5) {
                unsigned long long seed = pat_lru_seed ^ (long)expr;
 
                lru = lru64_get(XXH3(smp->data.u.str.area, smp->data.u.str.data, seed),
@@ -674,7 +674,7 @@ struct pattern *pat_match_beg(struct sample *smp, struct pattern_expr *expr, int
        }
 
        /* look in the list */
-       if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns)) {
+       if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns) && expr->ref->entry_cnt >= 20) {
                unsigned long long seed = pat_lru_seed ^ (long)expr;
 
                lru = lru64_get(XXH3(smp->data.u.str.area, smp->data.u.str.data, seed),
@@ -718,7 +718,7 @@ struct pattern *pat_match_end(struct sample *smp, struct pattern_expr *expr, int
        struct pattern *ret = NULL;
        struct lru64 *lru = NULL;
 
-       if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns)) {
+       if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns) && expr->ref->entry_cnt >= 20) {
                unsigned long long seed = pat_lru_seed ^ (long)expr;
 
                lru = lru64_get(XXH3(smp->data.u.str.area, smp->data.u.str.data, seed),
@@ -766,7 +766,7 @@ struct pattern *pat_match_sub(struct sample *smp, struct pattern_expr *expr, int
        struct pattern *ret = NULL;
        struct lru64 *lru = NULL;
 
-       if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns)) {
+       if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns) && expr->ref->entry_cnt >= 20) {
                unsigned long long seed = pat_lru_seed ^ (long)expr;
 
                lru = lru64_get(XXH3(smp->data.u.str.area, smp->data.u.str.data, seed),