Created
September 11, 2014 03:29
-
-
Save mattsta/65a07e304db4f99604c7 to your computer and use it in GitHub Desktop.
Quick redis integer size parsing tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Usage: ./size_parse INTEGER [1-5] */ | |
#include <stdio.h> | |
#include <stddef.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <sys/time.h> | |
#include <sys/types.h> | |
#include <inttypes.h> | |
#include <stdlib.h> | |
#include <string.h> | |
static long long ustime(void) { | |
struct timeval tv; | |
long long ust; | |
gettimeofday(&tv, NULL); | |
ust = ((long long)tv.tv_sec)*1e6; | |
ust += tv.tv_usec; | |
return ust; | |
} | |
inline int decDigitCount_div10(int64_t d) { | |
int l; | |
if (d < 0) { | |
l = 1; | |
d = -d; | |
} else { | |
l = 0; | |
} | |
while (d) { | |
l++; | |
d /= 10; | |
} | |
return l; | |
} | |
/* Return the number of digits of 'v' when converted to string in radix 10. | |
* See ll2string() for more information. */ | |
uint32_t digits10(uint64_t v) { | |
if (v < 10) return 1; | |
if (v < 100) return 2; | |
if (v < 1000) return 3; | |
if (v < 1000000000000UL) { | |
if (v < 100000000UL) { | |
if (v < 1000000) { | |
if (v < 10000) return 4; | |
return 5 + (v >= 100000); | |
} | |
return 7 + (v >= 10000000UL); | |
} | |
if (v < 10000000000UL) { | |
return 9 + (v >= 1000000000UL); | |
} | |
return 11 + (v >= 100000000000UL); | |
} | |
return 12 + digits10(v / 1000000000000UL); | |
} | |
size_t decDigitCount(int64_t d) { | |
size_t l = 0; | |
if (d < 0) { | |
d = -d; | |
l = 1; | |
} else { | |
l = 0; | |
} | |
if (d > 10000000000) goto its_really_big; | |
if (d < 10) return 1 + l; | |
if (d < 100) return 2 + l; | |
if (d < 1000) return 3 + l; | |
if (d < 10000) return 4 + l; | |
if (d < 100000) return 5 + l; | |
if (d < 1000000) return 6 + l; | |
if (d < 10000000) return 7 + l; | |
if (d < 100000000) return 8 + l; | |
if (d < 1000000000) return 9 + l; | |
if (d < 10000000000) return 10 + l; | |
its_really_big: | |
if (d < 100000000000) return 11 + l; | |
if (d < 1000000000000) return 12 + l; | |
if (d < 10000000000000) return 13 + l; | |
if (d < 100000000000000) return 14 + l; | |
if (d < 1000000000000000) return 15 + l; | |
if (d < 10000000000000000) return 16 + l; | |
if (d < 100000000000000000) return 17 + l; | |
if (d < 1000000000000000000) return 18 + l; | |
return 19 + l; | |
} | |
int main(int argc, char *argv[]) { | |
long long n = atoll(argv[1]); | |
long long init_n = n; | |
int which = atoi(argv[2]); | |
long long stopper = (long long)10e7; | |
size_t len = 0; | |
long long i; | |
long long start = ustime(); | |
if (which == 1) { | |
for (i = 0; i < stopper; i++) { | |
n = init_n; | |
len = 1; | |
if (n < 0) { | |
len++; | |
n = -n; | |
} | |
while((n = n/10) != 0) { | |
len++; | |
} | |
} | |
} else if (which == 2) { | |
for (i = 0; i < stopper; i++) { | |
len = decDigitCount(n); | |
} | |
} else if (which == 3) { | |
for (i = 0; i < stopper; i++) { | |
len = digits10(n); | |
} | |
} else if (which == 4) { | |
for (i = 0; i < stopper; i++) { | |
len = decDigitCount_div10(n); | |
} | |
} else if (which == 5) { | |
for (i = 0; i < stopper; i++) { | |
n = init_n; | |
if (n < 0) { | |
len = 1; | |
n = -n; | |
} else { | |
len = 0; | |
} | |
while (n) { | |
len++; | |
n /= 10; | |
} | |
} | |
} | |
long long end = ustime(); | |
printf("result: %lu for %d\n", len, which); | |
printf("duration: %llu\n", end-start); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example results compiled with
clang -O3 -o test test.c
:Compile different ways and test the performance changes: