読者です 読者をやめる 読者になる 読者になる

続brainf*ck

CLで無駄に実装3つ書いた。

リーダーマクロの例

* #^++++++++[>++++++++<-]>+.^
A
#(0 65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
1
* (multiple-value-list #4^+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+.^)
Hello, world!
(#(0 72 100 33) 3)

Brainf*ckスレに貼られていた素数探索のコードで速度とか比較してみる。
CL処理系はsbcl 1.0.22を使用。

ネタ再帰

Evaluation took:
  31.610 seconds of real time
  31.453125 seconds of total run time (31.390625 user, 0.062500 system)
  [ Run times consist of 0.422 seconds GC time, and 31.032 seconds non-GC time. ]
  99.50% CPU
  58,924,553,863 processor cycles
  2,612,290,480 bytes consed

普通の

Evaluation took:
  6.234 seconds of real time
  6.218750 seconds of total run time (6.218750 user, 0.000000 system)
  99.76% CPU
  11,625,169,955 processor cycles
  136,944 bytes consed

リーダーマクロ

Evaluation took:
  0.453 seconds of real time
  0.453125 seconds of total run time (0.453125 user, 0.000000 system)
  100.00% CPU
  821,685,004 processor cycles
  132,688 bytes consed

ちなみにリーダーマクロの展開結果はこんな感じ。

(let ((tape (make-array 100)) (pos 0))
  (incf pos 1)
  (incf (aref tape pos) 4)
  (loop while (< 0 (aref tape pos)) do (decf pos 1) (incf (aref tape pos) 8)
        (incf pos 1) (decf (aref tape pos) 1))
  (incf pos 1)
  (incf (aref tape pos) 7)
  (loop while (< 0 (aref tape pos)) do (decf pos 1) (incf (aref tape pos) 8)
        (incf pos 1) (decf (aref tape pos) 1))
  (decf pos 1)
  (incf (aref tape pos) 1)
  (incf pos 1)
  (incf (aref tape pos) 9)
  (incf pos 2)
  (incf (aref tape pos) 10)
  (loop while (< 0 (aref tape pos)) do (decf pos 1) (incf (aref tape pos) 10)
        (incf pos 1) (decf (aref tape pos) 1))
  (decf pos 1)
  (decf (aref tape pos) 2)
  (loop while (< 0 (aref tape pos)) do (incf pos 1)
        (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1))
        (decf pos 1)
        (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)
              (incf pos 1) (incf (aref tape pos) 1) (incf pos 1)
              (incf (aref tape pos) 1) (decf pos 2))
        (incf pos 2)
        (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)
              (decf pos 2) (incf (aref tape pos) 1) (incf pos 2))
        (decf pos 1) (decf (aref tape pos) 1)
        (loop while (< 0 (aref tape pos)) do (incf pos 1)
              (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1))
              (decf pos 2)
              (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)
                    (incf pos 2) (incf (aref tape pos) 1) (incf pos 1)
                    (incf (aref tape pos) 1) (decf pos 3))
              (incf pos 3)
              (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)
                    (decf pos 3) (incf (aref tape pos) 1) (incf pos 3))
              (decf pos 1) (incf (aref tape pos) 1)
              (loop while (< 0 (aref tape pos)) do (incf pos 2)
                    (loop while (< 0 (aref tape pos)) do
                          (decf (aref tape pos) 1))
                    (incf pos 1)
                    (loop while (< 0 (aref tape pos)) do
                          (decf (aref tape pos) 1))
                    (decf pos 2)
                    (loop while (< 0 (aref tape pos)) do (incf pos 1)
                          (incf (aref tape pos) 1) (incf pos 1)
                          (incf (aref tape pos) 1) (decf pos 2)
                          (decf (aref tape pos) 1))
                    (incf pos 2)
                    (loop while (< 0 (aref tape pos)) do (decf pos 2)
                          (incf (aref tape pos) 1) (incf pos 2)
                          (decf (aref tape pos) 1))
                    (decf pos 1) (incf pos 1)
                    (loop while (< 0 (aref tape pos)) do
                          (decf (aref tape pos) 1))
                    (incf (aref tape pos) 1) (decf pos 1)
                    (loop while (< 0 (aref tape pos)) do (incf pos 1)
                          (decf (aref tape pos) 1) (decf pos 1)
                          (loop while (< 0 (aref tape pos)) do
                                (decf (aref tape pos) 1)))
                    (incf pos 1)
                    (loop while (< 0 (aref tape pos)) do
                          (decf (aref tape pos) 1) (decf pos 4)
                          (loop while (< 0 (aref tape pos)) do
                                (decf (aref tape pos) 1) (incf pos 2)
                                (incf (aref tape pos) 1) (incf pos 2)
                                (incf (aref tape pos) 1) (decf pos 4))
                          (incf pos 4)
                          (loop while (< 0 (aref tape pos)) do
                                (decf (aref tape pos) 1) (decf pos 4)
                                (incf (aref tape pos) 1) (incf pos 4))
                          (decf pos 2) (incf (aref tape pos) 1) (incf pos 2))
                    (decf pos 2) (decf (aref tape pos) 1) (decf pos 1)
                    (decf (aref tape pos) 1))
              (incf pos 1) (incf pos 1)
              (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1))
              (incf (aref tape pos) 1) (decf pos 1)
              (loop while (< 0 (aref tape pos)) do
                    (loop while (< 0 (aref tape pos)) do
                          (decf (aref tape pos) 1))
                    (incf pos 1) (decf (aref tape pos) 1) (decf pos 1))
              (incf pos 1)
              (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)
                    (decf pos 1) (incf pos 2)
                    (loop while (< 0 (aref tape pos)) do
                          (decf (aref tape pos) 1))
                    (incf (aref tape pos) 1) (decf pos 4)
                    (loop while (< 0 (aref tape pos)) do
                          (decf (aref tape pos) 1))
                    (incf (aref tape pos) 1) (incf pos 3))
              (decf pos 3) (decf (aref tape pos) 1))
        (incf pos 4) (incf pos 1)
        (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1))
        (incf (aref tape pos) 1) (decf pos 1)
        (loop while (< 0 (aref tape pos)) do
              (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1))
              (incf pos 1) (decf (aref tape pos) 1) (decf pos 1))
        (incf pos 1)
        (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)
              (decf pos 8) (princ (code-char (aref tape pos))) (incf pos 3)
              (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1))
              (incf (aref tape pos) 6)
              (loop while (< 0 (aref tape pos)) do (decf pos 2)
                    (incf (aref tape pos) 8) (incf pos 2)
                    (decf (aref tape pos) 1))
              (decf pos 2) (princ (code-char (aref tape pos))) (incf pos 2)
              (incf (aref tape pos) 6)
              (loop while (< 0 (aref tape pos)) do (decf pos 2)
                    (decf (aref tape pos) 8) (incf pos 2)
                    (decf (aref tape pos) 1))
              (decf pos 4) (princ (code-char (aref tape pos))) (incf pos 9))
        (decf pos 6) (decf (aref tape pos) 1) (incf pos 2)
        (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1))
        (decf pos 3)
        (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)
              (incf pos 2) (incf (aref tape pos) 1) (incf pos 1)
              (incf (aref tape pos) 1) (decf pos 3))
        (incf pos 3)
        (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)
              (decf pos 3) (incf (aref tape pos) 1) (incf pos 3))
        (decf pos 1) (incf pos 1) (incf (aref tape pos) 1) (decf pos 1)
        (loop while (< 0 (aref tape pos)) do
              (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1))
              (incf pos 1) (decf (aref tape pos) 1) (decf pos 3)
              (decf (aref tape pos) 1) (incf pos 2))
        (incf pos 1)
        (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)
              (decf pos 3) (incf (aref tape pos) 9) (decf pos 1)
              (decf (aref tape pos) 1) (incf pos 4))
        (decf pos 2))
  (values tape pos))

おまけのbookmarklet用Javascript。スレに投下したら添削、じゃなくて一方的に100字ほど削ってもらえた。