NumPy vs Common Lisp 実行時間のみの比較

NumPyとCommon Lispの速度比較記事。処理系の起動時間も測ってしまっているので処理自体にかかっている時間を測って比較してみる。
環境は

Python 3.4.3 + Numpy

import numpy as np
import time

N = 100000

# Python版
def sumup(n):
    return sum(range(1, n + 1))

# NumPy版
def sumup(n):
    return np.arange(1, n + 1).sum()

def main():
    print("python with numpy start.")
    result = {}
    for count in range(1, N + 1):
        result[count - 1] = sumup(count)
    print("python with numpy end.")

start = time.time()
main()
elapsed_time = time.time() - start
print("elapsed_time:{0}".format(elapsed_time))

SBCL 1.3.11

(defparameter *n* 100000)

;; 1. 引数のみ型宣言
(defun sumup1 (n)
  (declare (type fixnum n))
  (let ((sum 0))
    (loop for i from 1 to n
          do (incf sum i))
    sum))

;; 2. 引数と局所変数で型宣言
(defun sumup2 (n)
  (declare (type fixnum n))
  (let ((sum 0))
    (declare (type fixnum sum))
    (loop for i from 1 to n
          do (incf sum i))
    sum))

;; 3. 引数と局所変数で型宣言 + 最適化宣言、実行時型チェック無効
(defun sumup3 (n)
  (declare (type fixnum n)
           (optimize (speed 3) (safety 0)))
  (let ((sum 0))
    (declare (type fixnum sum))
    (loop for i from 1 to n
          do (incf sum i))
    sum))

;; 4. 引数と局所変数で型宣言 + 最適化宣言、実行時型チェック無効、loop内で使う変数iも型宣言
(defun sumup4 (n)
  (declare (type fixnum n)
           (optimize (speed 3) (safety 0)))
  (let ((sum 0))
    (declare (type fixnum sum))
    (loop for i fixnum from 1 to n
          do (incf sum i))
    sum))

;; 5. 引数と局所変数で型宣言 + 最適化宣言、実行時型チェック無効、loop内で使う変数iも型宣言、引数と返値の型を宣言する
(declaim (ftype (function (fixnum) fixnum) sumup5))
(defun sumup5 (n)
  (declare (type fixnum n)
           (optimize (speed 3) (safety 0)))
  (let ((sum 0))
    (declare (type fixnum sum))
    (loop for i fixnum from 1 to n
          do (incf sum i))
    sum))

(defun main ()
  (print "common lisp start.")
  (loop for count from 1 to *n*
        collect (sumup5 count))
  (print "common lisp end."))

(time (main))

結果

結果はこのようになる。

ftypeの宣言があまり効いていないが、なんにせよCommon Lispに適切なチューニングを施すことによってNumPyを使ったときよりも3倍以上も速くなっていることが分かる。