whileループの文字数カウントはどのぐらい遅いか

文字列の長さを調べるのに、charをwhileループで回すか、4バイト単位でスキャンするか(strlen.c)、あるいは386依存の命令を使うか(strlen(3)=推定strlen.s)でどのぐらい速度が違うのか計ってみた。

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

int main(void) {
  int i, j, len;
  char *s;
  char *str[6] = {"foo", "bar", "hoge", "hello world",
		  "brown fox is something something",
		  "this sentence should be long enough"};

  for (i = 0; i < 100000000; i++) {
    for (j = 0; j < 6; j++) {
      s = str[j];
      while (*s++ != 0) len++;
      len = 0;
    }
  }
}
  :
  :
  for (i = 0; i < 100000000; i++) {
    for (j = 0; j < 6; j++) {
      len = strlen(str[j]);
    }
  }
  :
  :

という感じでループは1億回。適当な文字列のセットについて、それに含まれる文字列の長さを調べる。

結果は、

  • while: 46.6秒
  • strlen.c: 31.6秒
  • strlen(3): 1.7秒

むむ? strlen.cは思ったほど速くない。文字列が短すぎるのか? 本当は*str[]にいろんな長さの文字列を入れて計ろうと思ったけど、可変長の文字列を突っ込むポインタのポインタをさらさらと書けなくて、文字列セットを決め打ちにしてしまった、、、。まったく練習が足りないらしい。

同じことをRubyでもやってみた。

str = ["foo", "bar", "hoge", "hello world",
       "brown fox is something something",
       "this sentence should be long enough"]

1000000.times do
  str.each do |s|
    s.length
  end
end

それぞれループの回数を1桁、2桁減らして計ったものを1億回に換算した。