[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