Make strcmp do four byte comparisons on aligned strings.
Used libMicro's strcmp test to evaluate performance:
OPTS="-E -C 200 -S -W"
bin/strcmp $OPTS -N "strcmp_10" -s 10 -I 10
bin/strcmp $OPTS -N "strcmp_100" -s 100 -I 20
bin/strcmp $OPTS -N "strcmp_1k" -s 1k -I 50
bin/strcmp $OPTS -N "strcmp_10k" -s 10k -I 800
bin/strcmp $OPTS -N "strcmp_1m" -s 1m -I 500000
bin/strcmp $OPTS -N "strcmp_10m" -s 10m -I 5000000
Before:
prc thr usecs/call samples errors cnt/samp size
strcmp_10 1 1 0.02510 201 0 10000 10
strcmp_100 1 1 0.17520 169 0 5000 100
strcmp_1k 1 1 1.67700 177 0 2000 1024
strcmp_10k 1 1 17.24800 194 0 125 10240
strcmp_1m 1 1 17892.00000 160 0 1 1048576
strcmp_10m 1 1 183136.00000 201 0 1 10485760
After:
strcmp_10 1 1 0.01800 194 0 10000 10
strcmp_100 1 1 0.13540 190 0 5000 100
strcmp_1k 1 1 1.24950 188 0 2000 1024
strcmp_10k 1 1 12.85600 190 0 125 10240
strcmp_1m 1 1 12930.00000 170 0 1 1048576
strcmp_10m 1 1 134382.00000 195 0 1 10485760
This commit is contained in:
@@ -6,11 +6,28 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define LACKS_ZERO_BYTE(value) \
|
||||||
|
(((value - 0x01010101) & ~value & 0x80808080) == 0)
|
||||||
|
|
||||||
int
|
int
|
||||||
strcmp(char const *a, char const *b)
|
strcmp(char const *a, char const *b)
|
||||||
{
|
{
|
||||||
|
/* Make sure we don't pass page boundries on a or b when doing four byte
|
||||||
|
comparisons */
|
||||||
|
if ((((addr_t)a) & 3) == 0 && (((addr_t)b) && 3) == 0) {
|
||||||
|
uint32* a32 = (uint32*)a;
|
||||||
|
uint32* b32 = (uint32*)b;
|
||||||
|
|
||||||
|
while (LACKS_ZERO_BYTE(*a32)) {
|
||||||
|
int32 cmp = *a32++ - *b32++;
|
||||||
|
if (cmp != 0)
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
return *a32 - *b32;
|
||||||
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
int cmp = (unsigned char)*a - (unsigned char)*b++;
|
int cmp = (unsigned char)*a - (unsigned char)*b++;
|
||||||
if (cmp != 0 || *a++ == '\0')
|
if (cmp != 0 || *a++ == '\0')
|
||||||
|
|||||||
Reference in New Issue
Block a user