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 倍くらい差がありそうな様子は見える