JavaとPython両方を使っているとどれくらい速度に差があるのか確かめたくなったので、フィボナッチ数列生成プログラムで確かめてみます。体感はpythonの方がかなり遅いです。
目次
フィボナッチ数列生成プログラム
コンピューターサイエンス分野では何かと引っ張りだこの数列を用いて両者比較を行なっていきます。
条件
90番目のフィボナッチ数列を求める処理を1000回行った合計時間をナノ秒で出力。
方法はいろいろあるので分けて書きます。
Java
Java Array
JavaのArrayを使用して求めます。
public class fib {
long[] arrayF;
int n;
public static void main(String[] args){
long result = 0;
double t0 = System.nanoTime();
for (int i = 0;i<1000;i++){
fib Fib = new fib();
Fib.setN(90);
Fib.setArray();
Fib.calcF();
result = Fib.getFib();
}
System.out.println(result);
double t1 = System.nanoTime();
System.out.println((t1-t0));
}
public void calcF(){
for (int i = 2;i<n;i++){
arrayF[i] = arrayF[i-1] + arrayF[i-2];
}
}
public void setArray(){
arrayF = new long[n];
arrayF[0] = 0;
arrayF[1] = 1;
}
public void setN(int n){
this.n = n;
}
public fib(){
}
public long getFib(){
return arrayF[n-1];
}
}
実行結果
1779979416004714189
768334.0Java Arraylist
伸縮性のある便利なArraylistを使用します。
import java.util.ArrayList;
public class fib {
ArrayList<Long> arrayF ;
int n;
public static void main(String[] args){
long result = 0;
double t0 = System.nanoTime();
for (int i = 0;i<1000;i++){
fib Fib = new fib();
Fib.setN(90);
Fib.setArray();
Fib.calcF();
result = Fib.getFib();
}
System.out.println(result);
double t1 = System.nanoTime();
System.out.println((t1-t0));
}
public void calcF(){
for (int i = 2;i<n-1;i++){
arrayF.add(i,arrayF.get(i-1)+arrayF.get(i-2));
}
}
public void setArray(){
arrayF = new ArrayList<Long>();
arrayF.add(0,(long) 1);
arrayF.add(1,(long) 1);
}
public void setN(int n){
this.n = n;
}
public fib(){
}
public long getFib(){
return arrayF.get(n-2);
}
}
実行結果
1779979416004714189
4553584.0Arrayと比べて6倍ほど差が出ていることがわかります。
Java 変数の更新のみ
変数を更新していく方法ではn番目までの全ての数列をとっておくことはできませんが、どれくらい早くなるのかをみてみるために書いてみます。
public class fib {
int n;
long f;
public static void main(String[] args){
long result = 0;
double t0 = System.nanoTime();
for (int i = 0;i<1000;i++){
fib Fib = new fib();
Fib.setN(90);
Fib.calcF();
result = Fib.getFib();
}
System.out.println(result);
double t1 = System.nanoTime();
System.out.println((t1-t0));
}
public void calcF(){
long n1 = 1;
long n2 = 1;
for (int i = 0;i<n-3;i++){
f = n1 + n2;
n1 = n2;
n2 = f;
}
}
public void setN(int n){
this.n = n;
}
public fib(){
}
public long getFib(){
return f;
}
}
実行結果
1779979416004714189
524000.0Arrayよりも若干早いです。
Python
遅くなるだろうとは思いながらも、pythonでも書いていきます。
公平にするためにOOPで書きます。
Python Array
通常配列で計算します。
import time
class Fib:
def __init__(self,n) -> None:
self.n = n
self.array =[0 for i in range(n-1)]
def set_array(self):
self.array[0] = 1
self.array[1] = 1
def calcF(self):
for i in range(2,self.n-1):
self.array[i] = self.array[i-1] + self.array[i-2]
def getF(self):
return self.array[-1]
def main():
t0 = time.clock_gettime_ns(time.CLOCK_MONOTONIC)
for i in range(1000):
fib = Fib(90)
fib.set_array()
fib.calcF()
fibN = fib.getF()
print(fibN)
t1 = time.clock_gettime_ns(time.CLOCK_MONOTONIC)
print(t1-t0)
if __name__ == "__main__":
main()Python np.zeros()
NumPy zerosを使ってみます。
import numpy as np
import time
class Fib:
def __init__(self,n) -> None:
self.n = n
self.array = np.zeros(n-1)
def set_array(self):
self.array[0] = 1
self.array[1] = 1
def calcF(self):
for i in range(2,self.n-1):
self.array[i] = self.array[i-1] + self.array[i-2]
def get_fibN(self):
return self.array[-1]
def main():
t0 = time.clock_gettime_ns(time.CLOCK_MONOTONIC)
for i in range(1000):
fib = Fib(90)
fib.set_array()
fib.calcF()
fibN = fib.get_fibN()
print(fibN)
t1 = time.clock_gettime_ns(time.CLOCK_MONOTONIC)
print(t1-t0)
if __name__ == "__main__":
main()実行結果
1.779979416004714e+18
29064000

