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
