裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

プログラミングの歴史 -- 3(R と Python の速度比較)

2020年12月15日 | ブログラミング

歴史のついでに,Python と R の速度比較も

http://www.k-techlabo.org/www_python/lab_rep_speed1.pdf
円周軌道のダイナミクスのシミュレーション

で,Python と C の速度比較というのがやられている。

Python は C より 25 倍遅い!
でも,Cython だと C と同じくらいだったよ。

ということのようだ。

でも,Cython はほとんど C プログラムだ!

なんてこった!

==========================================

以下では,Cython はやらないけど,Pyhton, R, FORTRAN, AWK, C, JavaScript, Java を比較する!!!!

まずは,Python だ〜〜〜〜〜〜!

##### Python     calcf.py

dt = 0.00000001
x = 1
y = 0
for i in range(628318531):
    x -= y * dt
    y += x * dt
print('(x, y) = ({0:.15g}, {1:.15g})\n'.format(x, y))

$  time python3 calcf.py
(x, y) = (0.999999999999772, 2.8203875166645e-09)
253.265u 0.344s 4:13.84 99.9% 0+0k 0+0io 0pf+0w

遅い!!遅すぎる!!フリーズしたかと思ったぜ!!!

しかし,あせるな!!!
関数にすると precompile されるので速くなるということがあるんだよ。
逆に言えば,普通にやっちゃダメ。絶対,関数にしなさいということ。

def calcf():
 dt = 0.00000001
 x = 1
 y = 0
 for i in range(628318531):
     x -= y * dt
     y += x * dt
 print('(x, y) = ({0:.15g}, {1:.15g})\n'.format(x, y))

calcf()

$ time python3 calcf.py
(x, y) = (0.999999999999772, 2.8203875166645e-09)

92.849u 0.114s 1:33.03 99.9% 0+0k 0+0io 0pf+0w

な!!2.7倍速くなったぜ!!(何が3倍だ)

R はどうだ?

##### R     calcf.R

dt = 0.00000001
x = 1
y = 0
for (i in 0:628318530) {
    x = x - y * dt
    y = y + x * dt
}
cat(sprintf("(x, y) = (%.15g, %.15g)\n", x, y

$ time R --vanilla --quiet --no-echo -f calcf.R よりは,次のようにする
$ time Rscript calcf.R
(x, y) = ( 1 , 2.820388e-09 )
42.537u 0.134s 0:42.73 99.8% 0+0k 0+0io 0pf+0w

普通に!!Python(の関数版)より 2 倍速いぜ!!いぇいいぇいいぇい〜〜〜

R の場合は,Python の場合と違って,関数にしても差はない
つまり,関数にするしないにかかわらずプリコンパイルしているということだろう。

calcf = function() {
    dt = 0.00000001
    x = 1
    y = 0
    for (i in 0:628318530) {
        x = x - y * dt
        y = y + x * dt
    }
    cat('(x, y) = (', x, ',', y, ')\n')
}

calcf()

$ time Rscript calcf.R
(x, y) = ( 1 , 2.820388e-09 )
42.267u 0.135s 0:42.46 99.8% 0+0k 0+0io 0pf+0w

まあ,インタープリタ言語で,プリコンパイルするしないかでちょっとは差が出るが,コンパイル言語ならどうだ???って,やってみようじゃないか。

まずは,前にも言ったけど,一番最初に習った FORTRAN でやってみようじゃないか。

##### FORTRAN     calcf.f95

program calcf
 real(8) dt, x, y
 integer i
 dt = 0.00000001d0
 x = 1.0
 y = 0.0
    do i = 0, 628318531
        x = x - y * dt
        y = y + x * dt
    end do
    write(*, *) "(x, y) = (", x, ",", y, ")"
end program calcf

$ time gfortran calcf.f95; time ./a.out
0.038u 0.031s 0:00.07 85.7% 0+0k 0+0io 4pf+0w
 (x, y) = (  0.99999999999977196      ,   1.2820387516662219E-008 )
5.455u 0.011s 0:05.47 99.8% 0+0k 0+0io 0pf+0w

さすがコンパイル言語のレジェンド!!いぇいいぇいいぇい!!!!!

R の 7.8 倍の速度だ〜〜〜〜〜〜。驚くな。これが標準だ。

続いては,Pythonや R と同じくスクリプト言語の AWK のお出ましだ!!!
ものによっては ,R や Python より速いこともあるので,見逃せない御仁だ。

まあ,四の五の言わずにやってみよう。

##### AWK     calcf.awk

BEGIN {
    dt = 0.00000001
    x = 1
    y = 0
    for (i = 0; i
        x = x - y * dt
        y = y + x * dt
    }
    printf "(x, y) = (%.15g, %.15g)\n", x, y
}

$ time awk -f calcf.awk
(x, y) = (0.999999999999772, 2.8203875166645e-09)
167.086u 0.307s 2:47.60 99.8% 0+0k 0+0io 0pf+0w

うっ。がっくし。でもまあ,素の Python より 1.5 倍は速いぜ(ふ〜,心配させんなよ)

コンパイラ言語の大御所 C 様であらせられる。こころして,ご覧ぜよ。(はは〜〜〜っ)

##### C     calcf.c

#include

int main() {
 double dt, x, y;
 int i;
 dt = 0.00000001;
 x = 1;
 y = 0;
 for (i = 0; i
  x -= y * dt;
  y += x * dt;
 }
 printf("(x, y) = (%lg, %lg)\n", x, y);
}

$ time gcc calcf.c ; time ./a.out
0.045u 0.025s 0:00.07 85.7% 0+0k 0+0io 4pf+0w
(x, y) = (1, 2.82039e-09)
5.255u 0.007s 0:05.26 99.8% 0+0k 0+0io 0pf+0w

うむ。なんだかんだと,仰せられたが。FORTRAN 様と同じくらいだなぁ。

お次は,今はもう権勢も若干衰えたが,ひとときは C 様にもまさる勢いの Java 様じゃ。

どれどれ。お手並み拝見。

##### java     Calcf.java

import java.util.*;

public class Calcf {
 public static void main(String[] args) {
  double dt, x, y;
  int i;
     dt = 0.00000001;
          x = 1;
          y = 0;
          for (i = 0; i
              x -= y * dt;
              y += x * dt;
          }
          System.out.println("(x, y) = (" + x + "," + y + ")");
 }

}

$ time javac Calcf.java; time java Calcf
1.843u 0.112s 0:00.77 253.2% 0+0k 0+0io 3pf+0w
(x, y) = (0.999999999999772,2.820387516664499E-9)
3.238u 0.067s 0:03.21 102.4% 0+0k 0+0io 0pf+0w

ふうむ。実行速度は速いものの,FORTRAN 様や C 様の「コンパイル」あたるであろう javac と実行速度を合わせれば同じようなもの。だがしかし,javac は一時,その後は java だけでよいとならば,FORTRAN 様や C 様よりは速いのかなあ?そちども,どう思う?

いよいよ今回の最後であるが JavaScript だ。これは,計算言語とはちょっと違って,インタラクティブなインターネットページの構成に使われることが多いんだけど。一時,ユーザがデータを入力するだけで結果をお返しするというページ群を作っていたときにお世話になった言語じゃなあ。

インターネット上での記述とは少し違いがあるが,まあ,単独で動くプログラムとしては以下のようjに記述される。

#####  JavaScript     calcf.js

var dt, x, y;
var i;
dt = 0.00000001;
x = 1;
y = 0;
for (i = 0; i
    x -= y * dt;
    y += x * dt;
}

console.log('x =',x, 'y =', y);

$ time osascript -l JavaScript calcf.js
x = 0.999999999999772 y = 2.820387516664499e-9
5.006u 0.029s 0:05.07 99.0% 0+0k 0+0io 0pf+0w

結論としては,FORTRAN, C, Java と同じくらいの実行速度ということで,「コンパイラ言語」と言うことであろう。

ここまで,読んだ人はいるかな???

 

結論

1. プログラムの内容にもよるけど,やっぱり,コンパイラ言語は速いと言うこと。

2. 現在のところ,Python は R に比べて,ちっとも速くないよ。
むしろ,遅い。昔は速かったかもしれないけど。

3. Python プログラムが「他の言語に比べて読みやすい」というのは,眉唾。
慣れの問題もあるし,むしろ,読みにくく,保守しにくい

4. R よりも Python を使うというなら,たとえ 1 回しか使わないものでも,関数にしなさい(わるいこといわないから)

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Python 嫌いだけど,こんな Python プログラムはいやだ(その6)

2020年12月15日 | Python

d = 'a b c d e'

s = d.split()
label = []
for v in s:
    label.append(v)

というようなことをやっているが,作られる label は s と同じだ。つまり,3 行使って無駄なことをしている。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PVアクセスランキング にほんブログ村

PVアクセスランキング にほんブログ村