Skip to content

Instantly share code, notes, and snippets.

@ejrh
Created January 9, 2016 12:31
Show Gist options
  • Save ejrh/49957c53fa3b0fe452bb to your computer and use it in GitHub Desktop.
Save ejrh/49957c53fa3b0fe452bb to your computer and use it in GitHub Desktop.
// Inspired by https://www.reddit.com/r/programming/comments/400wpy/andrei_alexandrescus_amazing_150_minutes_course/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/times.h>
#include <time.h>
#define NUM_POWERS 19
static long long pow10[NUM_POWERS] = {
1000000000000000000,
100000000000000000,
10000000000000000,
1000000000000000,
100000000000000,
10000000000000,
1000000000000,
100000000000,
10000000000,
1000000000,
100000000,
10000000,
1000000,
100000,
10000,
1000,
100,
10,
1
};
long long baseline(char *data) {
long long result = 0;
int i = NUM_POWERS - strlen(data);
for (; *data; data++) {
result += pow10[i] * (*data - '0');
i++;
asm("");
}
return result;
}
static long long correction[NUM_POWERS];
// This version avoids subtracting '0' for each digit, and instead uses a one-off correction based on the number of digits
// (It is not actually better)
long long better(char *data) {
int i = NUM_POWERS - strlen(data);
long long result = correction[i];
for (; *data; data++) {
result += pow10[i] * (*data);
i++;
asm("");
}
return result;
}
#define NUM_TRIALS 10000000000L
double get_time() {
struct timespec ts;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
return (double) ts.tv_sec + (double) ts.tv_nsec / 1000000000.0;
}
int main() {
long long i;
correction[NUM_POWERS-1] = -48;
for (i = NUM_POWERS-2; i >= 0; i--) {
correction[i] = correction[i+1] - pow10[i] * 48;
}
printf("Basic test\n");
char *data = "123456789101112";
printf("data = '%s', result = %lld\n", data, baseline(data));
printf("data = '%s', result = %lld\n", data, better(data));
printf("Baseline benchmark\n");
double start, stop;
unsigned long long result = 0;
start = get_time();
for (i = 0; i < NUM_TRIALS; i++) {
result += baseline(data);
}
stop = get_time();
printf("Total result %llu\n", result);
printf("CPU time used = %lf\n", (stop - start));
printf("Better benchmark\n");
result = 0;
start = get_time();
for (i = 0; i < NUM_TRIALS; i++) {
result += better(data);
}
stop = get_time();
printf("Total result %llu\n", result);
printf("CPU time used = %lf\n", (stop - start));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment