文字列の繰り返し
rubyのソースコードを眺めていたらrb_str_timesの実装がおもしろかったので、実際そういった書き方をすることでどれだけパフォーマンスに差が出てくるのか試してみました。
#include <stdio.h> #include <stdlib.h> #include <string.h> inline unsigned long long rdtsc() { unsigned long long ret; __asm__ volatile ("rdtsc" : "=A" (ret)); return ret; } char *times_simple(char *str, size_t times) { size_t i, len = strlen(str); char *str2 = malloc(len*times + 1); for(i=0;i<len*times;i+=len) { memcpy(str2+i, str, len); } str2[len*times] = '\0'; return str2; } char *times_log(char *str, size_t times) { size_t n, len = strlen(str); char *str2 = malloc(len*times + 1); n = len; memcpy(str2, str, n); while(n <= len*times/2) { memcpy(str2+n, str2, n); n *= 2; } memcpy(str2+n, str2, len*times-n); str2[len*times] = '\0'; return str2; } int main(int argc, char **argv) { static char *str = "hoge"; char *str2; size_t times = 100; unsigned long long start, end; start = rdtsc(); str2 = times_simple(str, times); end= rdtsc(); printf("%s x %d = %s\n", str, times, str2); printf("time stamp counter: %llu\n", end - start); start = rdtsc(); str2 = times_log(str, times); end= rdtsc(); printf("%s x %d = %s\n", str, times, str2); printf("time stamp counter: %llu\n", end - start); return 0; }
memcpyを単純に100回繰り返すtimes_simpleと、memcpyの回数が8回で済むtimes_logの速度比較。時間計測はRDTSC命令で。
hoge x 100 = hogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge time stamp counter: 1871674 hoge x 100 = hogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge time stamp counter: 2430
すごく差がでました。
「アルゴリズムって大事ですね!」という締めはあちこちで見るので、ここでは「偉い人が書いたパーツを使って、なるべく自分でループとか書かないようにすると勝手に高速化されてたりしてて嬉しいですよ!」と言っておきます。
2009/2/2 2:46 追記
codepadの実行結果とかどういうものなのかいまいちわからんので手元の
% cat /proc/cpuinfo ... model name : AMD Athlon(tm)64 X2 Dual Core Processor 4600+ stepping : 1 cpu MHz : 1000.000 cache size : 512 KB ...
みたいなマシンの結果だと
hoge x 100 = hogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge time stamp counter: 135745 hoge x 100 = hogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge time stamp counter: 2326
この程度に。