[PATCH 01/12] filter: Minor optimizations, code cleanups in value comparison
Sergey Popovich
popovich_sergei at mail.ru
Mon Sep 30 20:22:15 CEST 2013
* Add minor optimisations on speed when comparing with int_cmp(),
uint_cmp(), u64_cmp(), by removing branching.
* Reorder type checks in val_compare() and val_in_range().
---
filter/filter.c | 64
++++++++++++++++++++++++-------------------------------
1 file changed, 28 insertions(+), 36 deletions(-)
diff --git a/filter/filter.c b/filter/filter.c
index 0fc10f1..f92ee9a 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -112,25 +112,22 @@ pm_format(struct f_path_mask *p, byte *buf,
unsigned int size)
*buf = 0;
}
-static inline int int_cmp(int i1, int i2)
+static inline int
+int_cmp(int i1, int i2)
{
- if (i1 == i2) return 0;
- if (i1 < i2) return -1;
- else return 1;
+ return (i1 > i2) - (i1 < i2);
}
-static inline int uint_cmp(unsigned int i1, unsigned int i2)
+static inline int
+uint_cmp(unsigned int i1, unsigned int i2)
{
- if (i1 == i2) return 0;
- if (i1 < i2) return -1;
- else return 1;
+ return (i1 > i2) - (i1 < i2);
}
-static inline int u64_cmp(u64 i1, u64 i2)
+static inline int
+u64_cmp(u64 i1, u64 i2)
{
- if (i1 == i2) return 0;
- if (i1 < i2) return -1;
- else return 1;
+ return (i1 > i2) - (i1 < i2);
}
/**
@@ -147,14 +144,11 @@ val_compare(struct f_val v1, struct f_val v2)
{
int rc;
- if ((v1.type == T_VOID) && (v2.type == T_VOID))
- return 0;
- if (v1.type == T_VOID) /* Hack for else */
- return -1;
- if (v2.type == T_VOID)
- return 1;
-
if (v1.type != v2.type) {
+ if (v1.type == T_VOID) /* Hack for else */
+ return -1;
+ if (v2.type == T_VOID)
+ return 1;
#ifndef IPV6
/* IP->Quad implicit conversion */
if ((v1.type == T_QUAD) && (v2.type == T_IP))
@@ -181,15 +175,13 @@ val_compare(struct f_val v1, struct f_val v2)
case T_PREFIX:
if (rc = ipa_compare(v1.val.px.ip, v2.val.px.ip))
return rc;
- if (v1.val.px.len < v2.val.px.len)
- return -1;
- if (v1.val.px.len > v2.val.px.len)
- return 1;
- return 0;
+ return int_cmp(v1.val.px.len, v2.val.px.len);
case T_PATH_MASK:
return pm_path_compare(v1.val.path_mask, v2.val.path_mask);
case T_STRING:
return strcmp(v1.val.s, v2.val.s);
+ case T_VOID:
+ return 0;
default:
debug( "Compare of unknown entities: %x\n", v1.type );
return CMP_ERROR;
@@ -408,18 +400,6 @@ val_in_range(struct f_val v1, struct f_val v2)
if (res != CMP_ERROR)
return res;
- - if ((v1.type == T_PREFIX) && (v2.type == T_PREFIX_SET))
- return trie_match_fprefix(v2.val.ti, &v1.val.px);
-
- if ((v1.type == T_CLIST) && (v2.type == T_SET))
- return clist_match_set(v1.val.ad, v2.val.t);
-
- if ((v1.type == T_ECLIST) && (v2.type == T_SET))
- return eclist_match_set(v1.val.ad, v2.val.t);
-
- if ((v1.type == T_PATH) && (v2.type == T_SET))
- return as_path_match_set(v1.val.ad, v2.val.t);
if (v2.type == T_SET)
switch (v1.type) {
@@ -436,7 +416,19 @@ val_in_range(struct f_val v1, struct f_val v2)
return 0;
return !! (val_simple_in_range(v1, n->from)); /* We turn CMP_ERROR
into compared ok, and that's fine */
}
+ case T_PATH:
+ return as_path_match_set(v1.val.ad, v2.val.t);
+ case T_CLIST:
+ return clist_match_set(v1.val.ad, v2.val.t);
+ case T_ECLIST:
+ return eclist_match_set(v1.val.ad, v2.val.t);
+ }
+ else if (v2.type == T_PREFIX_SET)
+ switch (v1.type) {
+ case T_PREFIX:
+ return trie_match_fprefix(v2.val.ti, &v1.val.px);
}
+
return CMP_ERROR;
}
-- 1.7.10.4
More information about the Bird-users
mailing list