#include <stdio.h>
#include <stdlib.h>
#include <linux/types.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <sys/time.h>#define A_SZ 1024*1024
unsigned char str[A_SZ] = { '\0' };
long long tv = 0;
unsigned long long _rdtsc()
{
union ts {
unsigned long long tx;
struct dword {
long tl, th;
} dw;
} t;
asm("rdtsc\n":"=a"(t.dw.tl), "=d"(t.dw.th));
return t.tx;
}
void gen_array()
{
int i, c;
srand(time(NULL));
for (i = 0; i < A_SZ;) {
c = rand() % 255;
if (!isprint(c))
continue;
str[i] = c;
i++;
}
printf("ARRAY SIZE: %d\n", i);
}
#define MEMCHR_MASK_GEN(mask) (mask *= 0x0101010101010101ULL)
void *new_memchr(const void *p, int c, size_t length)
{
__u64 mask, val;
const void *end = p + length;
c &= 0xff;
/* write(1, "strchr\n", 7); */
while ((long)p & (sizeof(long) - 1)) {
if (p >= end)
return NULL;
if (*(unsigned char *)p == c)
return (void *)p;
p++;
}
if (p <= end - 8) {
mask = c;
MEMCHR_MASK_GEN(mask);
for (; p <= end - 8; p += 8) {
val = *(__u64 *) p ^ mask;
if ((val + 0xfefefefefefefeffull) & (~val & 0x8080808080808080ull))
break;
}
}
for (; p < end; p++)
if (*(unsigned char *)p == c)
return (void *)p;
return NULL;
}
int main()
{
unsigned char ch;
char *ret = NULL;
int count = 0;
gen_array();
/* glibc */
tv = _rdtsc();
for (ch = 0x20; ch < 0x7E; ch++)
ret = memchr(str, ch, A_SZ);
printf("LIB: %lld\n", _rdtsc() - tv);
/* new */
tv = _rdtsc();
for (ch = 0x20; ch < 0x7E; ch++)
ret = new_memchr(str, ch, A_SZ);
printf("NEW: %lld\n", _rdtsc() - tv);
return (0);
}