実行効率

自分が十数年前にN88-BASICで書いたコードが出てきた。素数を表示するするプログラムである。習作としては定番だが、出てきたのは何の工夫もないあまりに無気力なものであった。便宜のため、UBASICで動作するように書き換えたものを示そう。

10 Maxnum=10000
20 for I=3 to Maxnum step 2
30 for J=2 to I-1
40 if I@J=0 then cancel for:goto 70
50 next J
60 print I;
70 next I

そして、多少の工夫を追加したものを先程schemeで書いてみた。

(use srfi-1)

(define (dividable? a b)
  (zero? (modulo a b)))

(define (make-prime-numbers maxnum)
  (let loop ((count 3) (primes '(2)))
    (if (< count maxnum)
        (loop (+ 2 count)
              (if (every
                   (let1 half (quotient count 2)
                     (lambda(x) (or (not (dividable? count x))
                                    (> x half))))
                   primes)
                  `(,@primes ,count)
                  primes))
        primes)))

(define (main arg)
  (write (make-prime-numbers 10000)))

ところが、比較しようと実際に動かして確認してみると10000程度までであれば速度差を体感することが出来なかった。もちろん正確に計測すれば何倍かの差はあるにしても絶対的な数値で見れば微々たるものだ。
当時、N88-BASICを動かしていたマシンはおそらく20MHz級のCPUを積んだものだったと思うのだが、素数を一個表示する度に数秒のタイムラグが入るような速度だった覚えがある。それが現代のマシンではなんでもない演算量なわけだ。もはや少々の工夫などどうでもよくなっている。
かつての私はCとアセンブリがあれば何でも出来ると思っていたのだが、今にして思えば馬鹿げたこだわりだ。用途にもよるが、個人が趣味として遊ぶ程度であれば現代の、あるいは近い将来のマシンにとってはネイティブコードであろうとJavaVMであろうと愚直なインタプリタであろうと実行効率の差は大した違いではない。だから、もしもある言語に対するこだわりがそういった効率に対するこだわりなのであれば、たまには他に目を向けてみるのも一興かと思う次第である。
C#導入してみようかな?
Document ID: d6cdb28a87bb17f6da24fb9395582dea