Unverified Commit de7f2f87 authored by debing.sun's avatar debing.sun Committed by GitHub
Browse files

Avoid overhead of comparision function pointer calls in lpFind() (#13503)



In #13279 (found by @filipecosta90), for custom lookups, we introduce a
comparison function for `lpFind()` to compare entry, but it also
introduces some overhead.

To avoid the overhead of function pointer calls:
1. Extract the lpFindCb() method into a lpFindCbInternal() method that
is easier to inline.
2. Use unlikely to annotate the comparison method, as can only success
once.

---------
Co-authored-by: default avatarOzan Tezcan <ozantezcan@gmail.com>
parent fb8755a6
...@@ -687,7 +687,7 @@ int lpGetIntegerValue(unsigned char *p, long long *lval) { ...@@ -687,7 +687,7 @@ int lpGetIntegerValue(unsigned char *p, long long *lval) {
* will be returned. 'user' is passed to this callback. * will be returned. 'user' is passed to this callback.
* Skip 'skip' entries between every comparison. * Skip 'skip' entries between every comparison.
* Returns NULL when the field could not be found. */ * Returns NULL when the field could not be found. */
unsigned char *lpFindCb(unsigned char *lp, unsigned char *p, static inline unsigned char *lpFindCbInternal(unsigned char *lp, unsigned char *p,
void *user, lpCmp cmp, unsigned int skip) void *user, lpCmp cmp, unsigned int skip)
{ {
int skipcnt = 0; int skipcnt = 0;
...@@ -707,7 +707,7 @@ unsigned char *lpFindCb(unsigned char *lp, unsigned char *p, ...@@ -707,7 +707,7 @@ unsigned char *lpFindCb(unsigned char *lp, unsigned char *p,
assert(p >= lp + LP_HDR_SIZE && p + entry_size < lp + lp_bytes); assert(p >= lp + LP_HDR_SIZE && p + entry_size < lp + lp_bytes);
} }
if (cmp(lp, p, user, value, ll) == 0) if (unlikely(cmp(lp, p, user, value, ll) == 0))
return p; return p;
/* Reset skip count */ /* Reset skip count */
...@@ -734,6 +734,12 @@ unsigned char *lpFindCb(unsigned char *lp, unsigned char *p, ...@@ -734,6 +734,12 @@ unsigned char *lpFindCb(unsigned char *lp, unsigned char *p,
return NULL; return NULL;
} }
unsigned char *lpFindCb(unsigned char *lp, unsigned char *p,
void *user, lpCmp cmp, unsigned int skip)
{
return lpFindCbInternal(lp, p, user, cmp, skip);
}
struct lpFindArg { struct lpFindArg {
unsigned char *s; /* Item to search */ unsigned char *s; /* Item to search */
uint32_t slen; /* Item len */ uint32_t slen; /* Item len */
...@@ -787,7 +793,7 @@ unsigned char *lpFind(unsigned char *lp, unsigned char *p, unsigned char *s, ...@@ -787,7 +793,7 @@ unsigned char *lpFind(unsigned char *lp, unsigned char *p, unsigned char *s,
.s = s, .s = s,
.slen = slen .slen = slen
}; };
return lpFindCb(lp, p, &arg, lpFindCmp, skip); return lpFindCbInternal(lp, p, &arg, lpFindCmp, skip);
} }
/* Insert, delete or replace the specified string element 'elestr' of length /* Insert, delete or replace the specified string element 'elestr' of length
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment