Skip to content

Instantly share code, notes, and snippets.

@mechanicker
Created July 7, 2013 12:59
Show Gist options
  • Save mechanicker/5943399 to your computer and use it in GitHub Desktop.
Save mechanicker/5943399 to your computer and use it in GitHub Desktop.
Optimizing strong compare
/* Time-stamp: <2013-07-07 10:37:24 dky> */
#include <stdio.h>
#include <string.h>
int stringcompare(const char*, const char*);
int stringcompareopt(const char *, size_t, const char *, size_t);
int stringcompare(const char *s1, const char *s2) {
size_t idx = 0;
int ret = 0;
if (s1 == s2) {
return 0;
} else if (NULL == s2) {
return 1;
} else if (NULL == s1) {
return -1;
}
/* Consider loop unrolling if string lenghts are known */
for (idx = 0; s1[idx] && s2[idx]; ++idx) {
if (s1[idx] < s2[idx]) {
ret = -1;
break;
} else if (s1[idx] > s2[idx]) {
ret = 1;
break;
}
}
if (0 == ret) {
/* Check if there is still data in the strings */
if (s1[idx]) {
ret = 1;
} else if (s2[idx]) {
ret = -1;
}
}
return ret;
}
int stringcompareopt(const char *s1, size_t l1, const char *s2, size_t l2) {
if (s1 == s2) {
return 0;
} else if (0 == l1 && 0 == l2) {
return 0;
} else if (NULL == s2) {
return 1;
} else if (NULL == s1) {
return -1;
}
/* Both strings are non zero length and have the same length */
size_t idx = 0;
size_t min = (l1 < l2) ? l1 : l2;
while (min - idx) {
if (sizeof(size_t) > (min - idx)) {
if (s1[idx] < s2[idx]) {
return -1;
} else if (s1[idx] > s2[idx]) {
return 1;
}
++idx;
} else { /* Loop unrolling */
size_t *u1 = (size_t *)(s1 + idx),
*u2 = (size_t *)(s2 + idx);
if (*u1 < *u2) {
return -1;
} else if (*u1 > *u2) {
return 1;
}
idx += sizeof(size_t);
}
}
int ret = l1 - l2;
if (ret < 0) {
ret = -1;
} else if (ret > 0) {
ret = 1;
}
return ret;
}
int main(int argc, char *argv[]) {
if (argc < 3) {
fprintf(stderr, "Usage: %s string1 string2\n", argv[0]);
return -1;
}
/* Use the library function to check for correctness */
printf("Comparing using strcmp: %d\n", strcmp(argv[1], argv[2]));
/* Byte-wise comparison */
printf("Comparing using stringcompare: %d\n", stringcompare(argv[1],
argv[2]));
/* If the string length is known: Unroll the loop */
printf("Comparing using stringcompareopt: %d\n",
stringcompareopt(argv[1], strlen(argv[1]),
argv[2], strlen(argv[2])));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment