strcpy と memcpy の性能の違いというやつを確認してみた

キャッシュがどうとかコアがどうとかは考えてない。

str.c

#include <string.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
  char *s = "hogehoge";
  char buf[255] = {0};
  long i = 0;
  long count = strtol(argv[1], NULL, 10);
  for (i = 0; i < count; ++i)
  {
    strcpy(&buf[0], s);
  }
}

mem.c

#include <string.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
  char *s = "hogehoge";
  char buf[255] = {0};
  long i = 0;
  long count = strtol(argv[1], NULL, 10);
  for (i = 0; i < count; ++i)
  {
    memcpy(&buf[0], s, 9);
  }
}

計測

% uname -a
Darwin mac-mini.local 10.7.0 Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386 i386

% cat test.sh
for f in *.c; do
  gcc -O0 ${f} -o ${f%.c}
done

for f in *.c; do
  target=${f%.c}
  for i in {1..10}; do
    count=`echo "10 ^ ${i}"|bc`
    echo "- target: ${target}"
    echo "  count: ${count}"
    echo "  result: |"
    /usr/bin/time -p ./${target} ${count}
  done
done

% zsh ./test.sh

結果

関数 (実行回数) real user sys
memcpy (1000000) 0.01 0.01 0.00
memcpy (10000000) 0.10 0.10 0.00
memcpy (100000000) 1.18 1.00 0.00
memcpy (1000000000) 11.20 10.06 0.04
memcpy (10000000000) 106.06 100.67 0.40
strcpy (1000000) 0.02 0.01 0.00
strcpy (10000000) 0.18 0.18 0.00
strcpy (100000000) 2.15 1.81 0.00
strcpy (1000000000) 21.32 18.14 0.12
strcpy (10000000000) 209.34 181.46 1.21

まとめ

  • この条件ではどこに根本的な要因があるかは言えない
  • とはいえ概ね 2 倍くらい差がありそうな様子は見える