さて,下請け関数をコンパイラ言語で書いたらどうなるかということで,私が一番とっつきやすい FORTRAN(雀百まで踊り忘れず)を使って,以下のようなプログラムを書いた。
function is_prime(x)
implicit none
integer(8) mx, x, i
logical is_prime
if (x == 2 .or. x == 3) then
is_prime = .true.
return
else if (x <= 1 .or. mod(x, 2) == 0 .or. mod(x, 3) == 0) then
is_prime = .false.
return
end if
mx = int(sqrt(float(x)))
do i = 5, mx, 6
if (mod(x, i) == 0) then
is_prime = (x == i)
return
else if (mod(x, i + 2) == 0) then
is_prime = (x == i + 2)
return
end if
end do
is_prime = .true.
end function is_prime
function next_prime(x)
implicit none
integer(8) x, i, next_prime
logical is_prime
x = x + 1
next_prime = 0
do i = x, 9223372036854775807_8 ! 巨大整定数の宣言 2^63 - 1
if (is_prime(i)) then
next_prime = i
return
end if
end do
end function next_prime
これを,
$ f2py -m prime_lib -c is_prime.f90
で
prime_lib.cpython-38-darwin.so
というシェアードライブラリを作る。
それを利用するには,まずインポートして
import prime_lib
prime_lib.next_prime() のようにする。
from time import time
start = time()
k = 9223372036854775782
print(f"next_prime({k}) = {prime_lib.next_prime(k)}")
print(time() - start)
実行結果は
next_prime(9223372036854775782) = 9223372036854775783
0.00039386 秒で答えが出る(小数点以下3桁の秒数なんてほぼゴミなので無視して良いレベル)。
Python で書いたプログラムでは 197.028 秒だったから,50万倍くらいの速度だ。
Julia で書いたプログラムでは 9.343 秒だったから,2万4千倍くらいの速度だ。
Julia は大健闘しているものの,やはりコンパイラ言語には太刀打ちできない。