Added pj_stricmp_alnum() to speedup the parser!!!
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@72 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
4f2be314a1
commit
a7944bb257
|
@ -334,10 +334,28 @@ PJ_IDECL(int) pj_strncmp2( const pj_str_t *str1, const char *str2,
|
|||
*
|
||||
* @return
|
||||
* - < 0 if str1 is less than str2
|
||||
* - 0 if str1 is identical to str2
|
||||
* - 0 if str1 is equal to str2
|
||||
* - > 0 if str1 is greater than str2
|
||||
*/
|
||||
PJ_IDECL(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2);
|
||||
PJ_IDECL(int) pj_stricmp(const pj_str_t *str1, const pj_str_t *str2);
|
||||
|
||||
/**
|
||||
* Perform lowercase comparison to the strings which consists of only
|
||||
* alnum characters. More over, it will only return non-zero if both
|
||||
* strings are not equal, and is not able to detect which string is
|
||||
* 'less'.
|
||||
*
|
||||
* If non-alnum inputs are given, then the function may mistakenly
|
||||
* treat two strings as equal while they're not.
|
||||
*
|
||||
* @param str1 The string to compare.
|
||||
* @param str2 The string to compare.
|
||||
*
|
||||
* @return
|
||||
* - 0 if str1 is equal to str2
|
||||
* - (-1) if not equal.
|
||||
*/
|
||||
PJ_IDECL(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2);
|
||||
|
||||
/**
|
||||
* Perform lowercase comparison to the strings.
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <pj/pool.h>
|
||||
|
||||
PJ_IDEF(pj_str_t) pj_str(char *str)
|
||||
{
|
||||
pj_str_t dst;
|
||||
|
@ -157,13 +159,49 @@ PJ_IDEF(int) pj_strcmp2( const pj_str_t *str1, const char *str2 )
|
|||
|
||||
PJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2)
|
||||
{
|
||||
pj_ssize_t diff;
|
||||
|
||||
diff = str1->slen - str2->slen;
|
||||
if (diff) {
|
||||
return (int)diff;
|
||||
register int len = str1->slen;
|
||||
if (len != str2->slen) {
|
||||
return (int)(len - str2->slen);
|
||||
} else if (len == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return pj_native_strnicmp(str1->ptr, str2->ptr, str1->slen);
|
||||
return pj_native_strnicmp(str1->ptr, str2->ptr, len);
|
||||
}
|
||||
}
|
||||
|
||||
PJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2)
|
||||
{
|
||||
register int len = str1->slen;
|
||||
|
||||
if (len != str2->slen) {
|
||||
return -1;
|
||||
} else if (len == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
register const pj_uint32_t *p1 = (pj_uint32_t*)str1->ptr,
|
||||
*p2 = (pj_uint32_t*)str2->ptr;
|
||||
while (len > 3 && (*p1 & 0x1F1F1F1F)==(*p2 & 0x1F1F1F1F))
|
||||
++p1, ++p2, len-=4;
|
||||
|
||||
if (len > 3)
|
||||
return -1;
|
||||
#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
|
||||
else if (len==3)
|
||||
return ((*p1 & 0x001F1F1F)==(*p2 & 0x001F1F1F)) ? 0 : -1;
|
||||
else if (len==2)
|
||||
return ((*p1 & 0x00001F1F)==(*p2 & 0x00001F1F)) ? 0 : -1;
|
||||
else if (len==1)
|
||||
return ((*p1 & 0x0000001F)==(*p2 & 0x0000001F)) ? 0 : -1;
|
||||
#else
|
||||
else if (len==3)
|
||||
return ((*p1 & 0x1F1F1F00)==(*p2 & 0x1F1F1F00)) ? 0 : -1;
|
||||
else if (len==2)
|
||||
return ((*p1 & 0x1F1F0000)==(*p2 & 0x1F1F0000)) ? 0 : -1;
|
||||
else if (len==1)
|
||||
return ((*p1 & 0x1F000000)==(*p2 & 0x1F000000)) ? 0 : -1;
|
||||
#endif
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <pj/string.h>
|
||||
#include <pj/pool.h>
|
||||
#include <pj/log.h>
|
||||
#include <pj/os.h>
|
||||
#include "test.h"
|
||||
|
||||
/**
|
||||
|
@ -63,6 +64,148 @@
|
|||
#define JUST_HELLO "Hello"
|
||||
#define UL_VALUE 3456789012UL
|
||||
|
||||
static int stricmp_test(void)
|
||||
{
|
||||
#define STRTEST(res,S1,S2,code) \
|
||||
do { \
|
||||
s1.ptr=S1; s1.slen=len; \
|
||||
s2.ptr=S2; s2.slen=len; \
|
||||
pj_get_timestamp(&t1); \
|
||||
if (pj_stricmp(&s1,&s2)!=res) return code; \
|
||||
pj_get_timestamp(&t2); \
|
||||
pj_sub_timestamp(&t2, &t1); \
|
||||
pj_add_timestamp(&e1, &t2); \
|
||||
pj_get_timestamp(&t1); \
|
||||
if (pj_stricmp_alnum(&s1,&s2)!=res) return code-1; \
|
||||
pj_get_timestamp(&t2); \
|
||||
pj_sub_timestamp(&t2, &t1); \
|
||||
pj_add_timestamp(&e2, &t2); \
|
||||
} while (0)
|
||||
|
||||
char *buf;
|
||||
pj_str_t s1, s2;
|
||||
pj_timestamp t1, t2, e1, e2, zero;
|
||||
pj_uint32_t c1, c2;
|
||||
int len;
|
||||
|
||||
e1.u32.hi = e1.u32.lo = e2.u32.hi = e2.u32.lo = 0;
|
||||
|
||||
pj_thread_sleep(0);
|
||||
|
||||
/* Compare empty strings. */
|
||||
len=0;
|
||||
STRTEST( 0, "","",-500);
|
||||
|
||||
/* equal, length=1
|
||||
* use buffer to simulate non-aligned string.
|
||||
*/
|
||||
buf = "a""A";
|
||||
len=1;
|
||||
STRTEST( 0, "a",buf+0,-510);
|
||||
STRTEST( 0, "a",buf+1,-512);
|
||||
|
||||
/* equal, length=2
|
||||
* use buffer to simulate non-aligned string.
|
||||
*/
|
||||
buf = "aa""Aa""aA""AA";
|
||||
len=2;
|
||||
STRTEST( 0, "aa",buf+0,-520);
|
||||
STRTEST( 0, "aa",buf+2,-522);
|
||||
STRTEST( 0, "aa",buf+4,-524);
|
||||
STRTEST( 0, "aa",buf+6,-524);
|
||||
|
||||
/* equal, length=3
|
||||
* use buffer to simulate non-aligned string.
|
||||
*/
|
||||
buf = "aaa""Aaa""aAa""aaA""AAa""aAA""AaA""AAA";
|
||||
len=3;
|
||||
STRTEST( 0, "aaa",buf+0,-530);
|
||||
STRTEST( 0, "aaa",buf+3,-532);
|
||||
STRTEST( 0, "aaa",buf+6,-534);
|
||||
STRTEST( 0, "aaa",buf+9,-536);
|
||||
STRTEST( 0, "aaa",buf+12,-538);
|
||||
STRTEST( 0, "aaa",buf+15,-540);
|
||||
STRTEST( 0, "aaa",buf+18,-542);
|
||||
STRTEST( 0, "aaa",buf+21,-534);
|
||||
|
||||
/* equal, length=4 */
|
||||
len=4;
|
||||
STRTEST( 0, "aaaa","aaaa",-540);
|
||||
STRTEST( 0, "aaaa","Aaaa",-542);
|
||||
STRTEST( 0, "aaaa","aAaa",-544);
|
||||
STRTEST( 0, "aaaa","aaAa",-546);
|
||||
STRTEST( 0, "aaaa","aaaA",-548);
|
||||
STRTEST( 0, "aaaa","AAaa",-550);
|
||||
STRTEST( 0, "aaaa","aAAa",-552);
|
||||
STRTEST( 0, "aaaa","aaAA",-554);
|
||||
STRTEST( 0, "aaaa","AaAa",-556);
|
||||
STRTEST( 0, "aaaa","aAaA",-558);
|
||||
STRTEST( 0, "aaaa","AaaA",-560);
|
||||
STRTEST( 0, "aaaa","AAAa",-562);
|
||||
STRTEST( 0, "aaaa","aAAA",-564);
|
||||
STRTEST( 0, "aaaa","AAaA",-566);
|
||||
STRTEST( 0, "aaaa","AaAA",-568);
|
||||
STRTEST( 0, "aaaa","AAAA",-570);
|
||||
|
||||
/* equal, length=5 */
|
||||
buf = "aaaAa""AaaaA""AaAaA""AAAAA";
|
||||
len=5;
|
||||
STRTEST( 0, "aaaaa",buf+0,-580);
|
||||
STRTEST( 0, "aaaaa",buf+5,-582);
|
||||
STRTEST( 0, "aaaaa",buf+10,-584);
|
||||
STRTEST( 0, "aaaaa",buf+15,-586);
|
||||
|
||||
/* not equal, length=1 */
|
||||
len=1;
|
||||
STRTEST( -1, "a", "b", -600);
|
||||
|
||||
/* not equal, length=2 */
|
||||
buf = "ab""ba";
|
||||
len=2;
|
||||
STRTEST( -1, "aa", buf+0, -610);
|
||||
STRTEST( -1, "aa", buf+2, -612);
|
||||
|
||||
/* not equal, length=3 */
|
||||
buf = "aab""aba""baa";
|
||||
len=3;
|
||||
STRTEST( -1, "aaa", buf+0, -620);
|
||||
STRTEST( -1, "aaa", buf+3, -622);
|
||||
STRTEST( -1, "aaa", buf+6, -624);
|
||||
|
||||
/* not equal, length=4 */
|
||||
buf = "aaab""aaba""abaa""baaa";
|
||||
len=4;
|
||||
STRTEST( -1, "aaaa", buf+0, -630);
|
||||
STRTEST( -1, "aaaa", buf+4, -632);
|
||||
STRTEST( -1, "aaaa", buf+8, -634);
|
||||
STRTEST( -1, "aaaa", buf+12, -636);
|
||||
|
||||
/* not equal, length=5 */
|
||||
buf="aaaab""aaaba""aabaa""abaaa""baaaa";
|
||||
len=5;
|
||||
STRTEST( -1, "aaaaa", buf+0, -640);
|
||||
STRTEST( -1, "aaaaa", buf+5, -642);
|
||||
STRTEST( -1, "aaaaa", buf+10, -644);
|
||||
STRTEST( -1, "aaaaa", buf+15, -646);
|
||||
STRTEST( -1, "aaaaa", buf+20, -648);
|
||||
|
||||
zero.u32.hi = zero.u32.lo = 0;
|
||||
c1 = pj_elapsed_cycle(&zero, &e1);
|
||||
c2 = pj_elapsed_cycle(&zero, &e2);
|
||||
|
||||
if (c1 < c2) {
|
||||
PJ_LOG(3,("", " error: pj_stricmp_alnum is slower than pj_stricmp!"));
|
||||
return -700;
|
||||
}
|
||||
|
||||
PJ_LOG(3, ("", " time: stricmp=%u, stricmp_alnum=%u (speedup=%d.%02dx)",
|
||||
c1, c2,
|
||||
(c1 * 100 / c2) / 100,
|
||||
(c1 * 100 / c2) % 100));
|
||||
return 0;
|
||||
#undef STRTEST
|
||||
}
|
||||
|
||||
int string_test(void)
|
||||
{
|
||||
const pj_str_t hello_world = { HELLO_WORLD, strlen(HELLO_WORLD) };
|
||||
|
@ -162,7 +305,8 @@ int string_test(void)
|
|||
|
||||
/* Done. */
|
||||
pj_pool_release(pool);
|
||||
return 0;
|
||||
|
||||
return stricmp_test();
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue