I was making the claim somewhere that NUL-termination made string
copying slower.  It occurred to me that I ought to test that before
making the assertion; indeed, this program shows that at the
one-kilobyte level on my laptop, it's slower by about a factor of 6.

#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

double now() {
  static struct timeval tv;
  gettimeofday(&tv, 0);
  return tv.tv_sec + tv.tv_usec / 1000000.0;
}

float seconds_per_call(void (*f)()) {
  double start = now(), end;
  int i = 0;
  for (;;) {
    f(); f(); f(); f(); f();  f(); f(); f(); f(); f();
    f(); f(); f(); f(); f();  f(); f(); f(); f(); f();
    f(); f(); f(); f(); f();  f(); f(); f(); f(); f();
    f(); f(); f(); f(); f();  f(); f(); f(); f(); f();
    f(); f(); f(); f(); f();  f(); f(); f(); f(); f();

    f(); f(); f(); f(); f();  f(); f(); f(); f(); f();
    f(); f(); f(); f(); f();  f(); f(); f(); f(); f();
    f(); f(); f(); f(); f();  f(); f(); f(); f(); f();
    f(); f(); f(); f(); f();  f(); f(); f(); f(); f();
    f(); f(); f(); f(); f();  f(); f(); f(); f(); f();
    i += 100;
    end = now();
    if (end - start > 1.0)
      return (end - start) / i;
  }
}

void nop() { }

#define bufsiz 1024
char src[bufsiz], dst[bufsiz];
void init_buf() {
  int i;
  for (i = 0; i != bufsiz; i++) src[i] = 'x';
  src[bufsiz-1] = '\0';
}
void strcpy_buf() {
  strcpy(dst, src);
}
void memcpy_buf() { 
  memcpy(dst, src, bufsiz);
}

void test_performance(void (*f)(), char *name) {
  static float seconds_per_call_nop = 0.0;
  if (seconds_per_call_nop == 0.0)
    seconds_per_call_nop = seconds_per_call(nop);
  printf("%s: %g s/call\n", name, seconds_per_call(f) - seconds_per_call_nop);
}
#define test(x) test_performance(x, #x)

int main(int argc, char **argv) {
  init_buf();
  test(nop);
  test(strcpy_buf);
  test(memcpy_buf);
  return 0;
}

Reply via email to