Hi,

I wanted to try to speed up eina_stringshare_del,
but I ended touching eina_stringshare_add first.

p0.patch: _eina_share_common_find_hash(…)
            merges _eina_share_common_cmp and calls to eina_rbtree_inline_lookup

p1.patch: eina_stringshare API
            treat big strings first and avoid a call from eina_stringshare_add

Cheers,
Jérémy

diff --git a/eina/src/lib/eina_share_common.c b/eina/src/lib/eina_share_common.c
index 91ad0db..247fae7 100644
--- a/eina/src/lib/eina_share_common.c
+++ b/eina/src/lib/eina_share_common.c
@@ -334,17 +334,6 @@ static void _eina_share_common_population_head_del(
 }
 #endif
 
-static int
-_eina_share_common_cmp(const Eina_Share_Common_Head *ed,
-                       const int *hash,
-                       __UNUSED__ int length,
-                       __UNUSED__ void *data)
-{
-   EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(ed, , 0);
-
-   return ed->hash - *hash;
-}
-
 static Eina_Rbtree_Direction
 _eina_share_common_node(const Eina_Share_Common_Head *left,
                         const Eina_Share_Common_Head *right,
@@ -511,12 +500,22 @@ 
_eina_share_common_head_remove_node(Eina_Share_Common_Head *head,
    return 0;
 }
 
-static Eina_Share_Common_Head *
+static inline Eina_Share_Common_Head *
 _eina_share_common_find_hash(Eina_Share_Common_Head *bucket, int hash)
 {
-   return (Eina_Share_Common_Head *)eina_rbtree_inline_lookup
-             (EINA_RBTREE_GET(bucket), &hash, 0,
-             EINA_RBTREE_CMP_KEY_CB(_eina_share_common_cmp), NULL);
+   int result;
+   const Eina_Share_Common_Head *root = bucket;
+
+   while (root)
+     {
+        EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(root, , 0);
+        result =  root->hash - hash;
+        if (result == 0) return (Eina_Share_Common_Head*) root;
+
+        root = (Eina_Share_Common_Head*)EINA_RBTREE_GET(root)->son[result < 0 
? 0 : 1];
+     }
+
+   return NULL;
 }
 
 static Eina_Share_Common_Node *
diff --git a/eina/src/lib/eina_stringshare.c b/eina/src/lib/eina_stringshare.c
index 2a457f4..9d48f5a 100644
--- a/eina/src/lib/eina_stringshare.c
+++ b/eina/src/lib/eina_stringshare.c
@@ -582,28 +582,17 @@ eina_stringshare_del(Eina_Stringshare *str)
      return;
 
    /* special cases */
-   if (str[0] == '\0')
-     slen = 0;
-   else if (str[1] == '\0')
-     slen = 1;
-   else if (str[2] == '\0')
-     slen = 2;
-   else if (str[3] == '\0')
-     slen = 3;
-   else
-     slen = 4;  /* handled later */
-
-   if (slen < 2)
+   if (str[0] == '\0' || str[1] == '\0')
      return;
-   else if (slen < 4)
+   else if (str[2] == '\0' || str[3] == '\0')
      {
+        slen =  (str[2] == '\0') ? 2 : 3;
         eina_share_common_population_del(stringshare_share, slen);
         eina_lock_take(&_mutex_small);
         _eina_stringshare_small_del(str, slen);
         eina_lock_release(&_mutex_small);
         return;
      }
-
    if (!eina_share_common_del(stringshare_share, str))
      CRITICAL("EEEK trying to del non-shared stringshare \"%s\"", str);
 }
@@ -611,45 +600,50 @@ eina_stringshare_del(Eina_Stringshare *str)
 EAPI Eina_Stringshare *
 eina_stringshare_add_length(const char *str, unsigned int slen)
 {
+   const char *s;
+
    if (!str)
      return NULL;
-   else if (slen == 0)
-     return "";
+
+   if (slen >3)
+     return eina_share_common_add_length(stringshare_share, str, slen *
+                                       sizeof(char), sizeof(char));
    else if (slen == 1)
      return (Eina_Stringshare *) _eina_stringshare_single + ((*str) << 1);
-   else if (slen < 4)
-     {
-        const char *s;
+   else if (slen <= 0)
+     return "";
 
-        eina_lock_take(&_mutex_small);
-        s = _eina_stringshare_small_add(str, slen);
-        eina_lock_release(&_mutex_small);
-        return s;
-     }
+   eina_lock_take(&_mutex_small);
+   s = _eina_stringshare_small_add(str, slen);
+   eina_lock_release(&_mutex_small);
 
-   return eina_share_common_add_length(stringshare_share, str, slen *
-                                       sizeof(char), sizeof(char));
+   return s;
 }
 
 EAPI Eina_Stringshare *
 eina_stringshare_add(const char *str)
 {
    int slen;
+   const char *s;
+
    if (!str)
      return NULL;
 
-   if      (str[0] == '\0')
-     slen = 0;
-   else if (str[1] == '\0')
-     slen = 1;
-   else if (str[2] == '\0')
-     slen = 2;
-   else if (str[3] == '\0')
-     slen = 3;
-   else
-     slen = 3 + (int)strlen(str + 3);
+   slen = (int)strlen(str);
 
-   return eina_stringshare_add_length(str, slen);
+   if (slen >3)
+     return eina_share_common_add_length(stringshare_share, str, slen *
+                                       sizeof(char), sizeof(char));
+   else if (slen == 1)
+     return (Eina_Stringshare *) _eina_stringshare_single + ((*str) << 1);
+   else if (slen <= 0)
+     return "";
+
+   eina_lock_take(&_mutex_small);
+   s = _eina_stringshare_small_add(str, slen);
+   eina_lock_release(&_mutex_small);
+
+   return s;
 }
 
 EAPI Eina_Stringshare *
@@ -726,41 +720,28 @@ EAPI Eina_Stringshare *
 eina_stringshare_ref(Eina_Stringshare *str)
 {
    int slen;
+   const char *s;
 
    if (!str)
      return eina_share_common_ref(stringshare_share, str);
 
-   /* special cases */
-   if      (str[0] == '\0')
-     slen = 0;
-   else if (str[1] == '\0')
-     slen = 1;
-   else if (str[2] == '\0')
-     slen = 2;
-   else if (str[3] == '\0')
-     slen = 3;
-   else
-     slen = 3 + (int)strlen(str + 3);
+   slen = (int)strlen(str);
 
-   if (slen < 2)
+   if (slen >3)
+     return eina_share_common_ref(stringshare_share, str);
+   else if (slen < 2)
      {
         eina_share_common_population_add(stringshare_share, slen);
 
         return str;
      }
-   else if (slen < 4)
-     {
-        const char *s;
-        eina_share_common_population_add(stringshare_share, slen);
 
-        eina_lock_take(&_mutex_small);
-        s = _eina_stringshare_small_add(str, slen);
-        eina_lock_release(&_mutex_small);
-
-        return s;
-     }
+   eina_share_common_population_add(stringshare_share, slen);
+   eina_lock_take(&_mutex_small);
+   s = _eina_stringshare_small_add(str, slen);
+   eina_lock_release(&_mutex_small);
 
-   return eina_share_common_ref(stringshare_share, str);
+   return s;
 }
 
 EAPI int

<<attachment: Stringshare-trunk.png>>

<<attachment: Stringshare-p0.png>>

<<attachment: Stringshare-p1.png>>

<<attachment: Stringshare-p0p1.png>>

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_sfd2d_oct
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to