2019年1月10日木曜日

Pythonの長所と短所についての考察(シェアしました。)

勉強の為に転載しました。
https://qiita.com/KatsunoriNakamura/items/dd567ea7cfaa99685453




に更新
Pythonは大変に良い言語です.
多くの高機能,高性能なパッケージ(モジュール)が提供されており,情報工学の知識に疎遠な人にも高度な情報処理が実現できる,とてもありがたいプログラミングプラットフォームであることは疑う余地がないと思います.
 
ただしPythonを盲信,過信するのはよくありません.
それで,Pythonの長所と短所を良く理解して,有効に活用するための参考となればと思い,この記事を書いています.
他の言語処理系とPythonの良いところを組み合わせていくというのが正しい使い方だと思います.
 
Pythonを学ぶためのテキストはこれをベースにしています.
→Pythonのテキスト作りました

Pythonの実行時間に関する実験

● 円軌道のシミュレーションで速度比較(C vs Python, Cython vs Python)
 これは流石にC言語の圧勝ですね.Cの方がPythonより25倍以上早いという結果を示しています.ただし,この程度の単純な数値計算プログラムの場合はCythonを使うと,Pythonのプログラムに大きな変更をすることなくC言語に匹敵する速度が得られることもわかります.
 
● マンデルブロ集合の画像生成(JavaScript vs Python, Cython vs Python)
 Mandelbrot集合を1024×1024のサイズの画像として可視化するサンプルです.
(速度比較に使用した実行環境は Windows10, Intel Core i7-5500U 2.39GHz です)
 → HTML5(JavaScript)による実装例
  `start'ボタンをクリックして実行
  実行時間は平均 0.231 秒でした.(Google Chrome使用)
 → Python+Pillowによる実装例
  ダウンロード後,
  py MandelbrotPython.py m.png -2.0 2.0 -2.0 2.0
  として実行する.(画像が m.png に生成される)
  平均実行時間は 53.645 秒でした.
 実行時間を比べると 232.23 倍でした.
 Pillowを呼び出す部分をコメントアウトしても実行時間に目立った影響はありません.
 JavaScriptの圧勝ですね.もちろん,実行するブラウザによってもかなり差が出ますが,
 それでも2桁倍の勝利ですね.
 → Cython+Pillowによる実装例
  ダウンロード後にCython処理系でコンパイルしてPythonモジュールにしてから
  import MandelbrotPyx
  MandelbrotPyx.MakeMandelbrot('m2.png',-2.0,2.0,-2.0,2.0)
 などとして実行します.同じ計算機環境での実行時間は平均で7.601秒
 でした.Cythonで処理することで約7倍のスピードアップができました.
 (まだ最適化できる余地があります)
 
全く余談ですが,最近はJavaとJavaScriptの実行速度がCに迫ってきていますね.
(JavaScriptの超入門テキスト作っています)
 
● リスト/セット/辞書 の速度比較
 Pythonは大量のデータをオンメモリで処理するには良い環境です.ただし,使用するデータ構造の種類は適切に使い分ける必要があります.でないと,実用に耐えない程に処理時間がかかってしまうことにもなります.Pythonのリスト/セット/辞書の処理時間に関するテストをしてみました.
 →データ構造の処理時間に関する試み(Pythonのテキストから抜粋:テキスト本体
 ・サンプルプログラム:spdTest00.pyspdTest01.pyspdTest02.py
整数インデックスで配列のように扱う場合はPythonのリストは高速ですが,要素の探索はだめですね.おそらく「線形探索」やっていると思われます.要素の探索の場合はセットや辞書を使わねばなりません.
 
(つづく)

Pythonの何が良いのか

■ 学びやすさと機能性

 Pythonは初心者に優しい言語です.それでいて高機能な言語です.
学校でCやJavaのプログラミングを習ったことがある人は痛感していると思いますが,最初は全く意味がわからないわけです.基本となるアルゴリズム(手順のアイデア)とは関係のない「語」を大量に書き並べないと動かない…
そんな意味不明の「語」に対して,私たち教師は「はじめはわからなくていいから…」とか「おまじないだと思って!」とか釈明するわけです.
 
 それに対してPythonは「意味不明の語」がものすごく少ないです.例えば学校で最初によくやるレッスン「"Hello,World"を表示するプログラム」を作るにしても,JavaとPythonの違いが大きいです.実際にJavaとPythonのプログラムを書いてみて比較してみます.
 
 → Java版「Hello,World」(5行)
 → Python版「Hello,World」(1行)
 
次にGUIで"Hello,World"表示するサンプルを示します.
 
 → Java版「Hello,World」(33行:JavaFX版)
 → Python版「Hello,World」(17行:Kivy版)
 → Python版「Hello,World」(8行:Tkinter版)
 
たったこれだけの入門レッスンでもプログラムの行数が格段に違うわけです.(Pythonの方が短い)
さらにPythonでは,やりたいことを直接表現できる書き方がたくさん許されていて,プログラミングの生産性がものすごく高いです.(詳しくはPythonを学んでください)
CやJavaの場合ではたくさん記述しないといけないような高度な処理がPythonでは予め用意されていて,しかもそれらが簡単に呼び出せる.ありがたいですね.
 
現場で教えている実感です.
 
一応ですが誤解を避けるために解説しますが,C言語を学ぶ意味は大変に大きいです.(Pythonインタプリタ自体がCで書かれています)
デバイス制御の根本,記憶資源の扱いの根本,入出力の根本,通信の根本,プロセス管理の根本…
情報工学の根本を学ぶ場合にはCは避けて通れません.
(更に言いますと,Windows, macOS, LinuxといったOSもその大部分がCで書かれています)
 
Pythonが身についたら是非C言語を学んでください.
Cでモジュール作ってPythonから操るというのが理想です.
Cython, Numba という選択肢もありますが,C言語で書いた関数をctypes経由で呼び出すというのがとても良いかと思います.
 

■ 豊富なパッケージ

 Pythonの良さは何と言ってもパッケージ(モジュール)の多さだと思います.私のゼミでも「画像認識というのをやってみたいんですけど…」と言い出した学生(まだ3年生)に迅速に対応できました.今では制作物と卒論のアウトラインを練るに至っています.もちろん,その学生君はプログラミングが得意というわけでもありません.
C++ や Java ではこのスピードで学生の要望に対応するのは不可能ですね.
Python+OpenCV+Pillowの勝利です.
 誤解しないでいただきたいのですが,Python本体は遅いですが,各種パッケージはCで実装されている場合が多く,とても高速です.顕著な例としては,数値演算処理やる場合にPython+NumPy使うと,下手にCやFORTRANで書くより早いことが挙げられます.
 あとSymPyとかChainer… 「これを無料で公開しても良いのか?」というレベルのソフトウェア.私自身,Pythonの世界に足を踏み入れた瞬間に「何だ,これは!」,「こんなのありか?!」と驚いた程の豊かさです.
 PythonがAI用の言語であるかのような認識があるのも,関連パッケージの豊富さに起因していますね.これも誤解が多いことですが,元々PythonはAI用の言語ではありません.あまりの利便性をAI研究者たちが重宝しているということです.
 

■ データ構造に則したプログラミング

 Pythonのリストやタプルなどのデータ構造につける添字(スライス)は表現力が高く,データ構造の内部にアクセスするのが容易です.さらに,map,filterなどの関数やlambda表現の使用に慣れてくると,データ構造をそのまま反映する形のプログラミングができます.
 うまくするとforによるループを減らし,プログラム全体を簡潔に書き上げることができますので,是非学んでください.
 

■ evalやexecによる「メタプログラミング」

 これに関してはプログラミングをやりこなしてからでないと理解しにくいと思いますが,「データをプログラムとして実行できる」という高度な処理です.文字列データとして作成した式や文を実行できる機能です.(データをプログラムとして実行する機能はAI系プログラミングには必須の機能です) 私事ですが,研究活動にもうLispはあまり必要なくなる感じがしています.
 
今では私の所では,AI系のテーマに取り組むのに必要な言語は,
Python:システムの統括
・C/C++:速度を要求する部分の開発
Prolog:論理プログラミングと制約充足に使用
の3つになっています.

0 コメント:

コメントを投稿