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の圧勝ですね.もちろん,実行するブラウザによってもかなり差が出ますが,それでも桁違いの勝利ですね.
→ 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の超入門テキスト,Javaの超入門テキスト作っています)
● リスト/セット/辞書 の速度比較
Pythonは大量のデータをオンメモリで処理するには良い環境です.ただし,使用するデータ構造の種類は適切に使い分ける必要があります.でないと,実用に耐えない程に処理時間がかかってしまうことにもなります.Pythonのリスト/セット/辞書の処理時間に関するテストをしてみました.
→データ構造の処理時間に関する試み(Pythonのテキストから抜粋:テキスト本体)
・サンプルプログラム:spdTest00.py,spdTest01.py,spdTest02.py
整数インデックスで配列のように扱う場合はPythonのリストは高速ですが,要素の探索はだめですね.おそらく「線形探索」やっていると思われます.要素の探索の場合はセットや辞書を使わねばなりません.
● NumPyあり/なしとC言語プログラムの速度比較
Pythonを使う目的として大きいものの1つがデータ処理です.データサイエンス,機械学習のためのライブラリの多くがNumPyを基盤に作られています.そんな状況がありますので,NumPyがどのくらい早いかを行列の積を求めるプログラムを作って調べました.
行列の積を求めるプログラム3種の比較(PDFのレポート)
(Pythonのテキストから抜粋:テキスト本体)
プログラム:matmult01.py,matmult01_np.py,matmult01.c
リストを配列に見立てて行列の積を計算するのに比べると,NumPyは1万倍以上の早さが出るわけですね.速度比を見たとき「何かの間違いかな?」と思ってしまいました.
更に,C言語で素朴に記述するよりも30倍以上の速度です.
このケースではPython+NumPyの圧勝です.
__注)__Intel MKLを用いたNumPyの場合です.MKLなしのNumPyの場合はもっと遅くなります.
(補足) 特にNumPyの行列演算(線形代数の計算)は高速で,実現したい処理が行列の計算として記述できる場合は実行速度が大幅に向上できる場合があります.
(→PDFレポート:NumPyの行列の積の高速性を示す例)
これは「Python3ライブラリブック」からの抜粋です.
(つづく)
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とかscikit-learn,Keras,PyTorch… 「これを無料で公開しても良いのか?」というレベルのソフトウェア.私自身,Pythonの世界に足を踏み入れた瞬間に「何だこれは!」,「こんなのありか?!」と驚いた程の豊かさです.
PythonがAI用の言語であるかのような認識があるのも,関連ライブラリの豊富さに起因していますね.これも誤解が多いことですが,元々PythonはAI用の言語ではありません.あまりの利便性をAI研究者たちが重宝しているということです.
機械学習用のscikit-learn,TensorFlowなどを操るKerasといったライブラリは機械学習/AI分野の標準的なライブラリで,「Pythonが前提」となっています.
■ データ構造に則したプログラミング
Pythonのリストやタプルなどのデータ構造につける添字(スライス)は表現力が高く,データ構造の内部にアクセスするのが容易です.さらに,map,filterなどの関数やlambda表現の使用に慣れてくると,データ構造をそのまま反映する形のプログラミングができます.
うまくするとforによるループを減らし,プログラム全体を簡潔に書き上げることができますので,是非学んでください.
■ evalやexecによる「メタプログラミング」
これに関してはプログラミングをやりこなしてからでないと理解しにくいと思いますが,「データをプログラムとして実行できる」という高度な処理です.文字列データとして作成した式や文を実行できる機能です.(データをプログラムとして実行する機能はAI系プログラミングには必須の機能です) 私事ですが,研究活動にもうLispはあまり必要なくなる感じがしています.(→訂正:やっぱりLispは重要ですね)
今では私の所では,AI系のテーマに取り組むのに必要な言語は,
・Python:システムの統括
・C/C++:速度を要求する部分の開発
・Prolog:論理プログラミングと制約充足/解消に使用
の3つになっています.
(PythonからPrologの機能を簡単に呼び出すライブラリがあります)
Pythonの「学びやすさ」関する注意事項
Pythonの言語としての表記法のわかりやすさ,記述の柔軟性は誰しもが認めるところですが,決して勘違いしてはいけない部分もあります.
初心者に優しいPythonですが,決して「学ぶべき項目が少ない」ということではありません.多くの書籍や教育コースでは「Pythonは短時間で習得できる」と主張していますが,他人が書いたPythonプログラムを読みこなしたり,多くのライブラリを使いこなすことができるようになるには,結局,かなりの量の学習が余儀なくされます.(私の実感としては,他の言語より学ぶべき項目は多いように思います)
確かにPythonプログラミングに「入門」して学習を開始する段階では,他の言語にはないわかりやすさと優しさがありますが,Pythonは非常に奥の深い言語です.「速習」で概観がつかめたら,その後は時間をかけてじっくりと学んでほしいと思います.うっかりすると「Pythonは入門者用の底の浅い言語だ」と勘違いしてしまう恐れがありますが,そのような誤解は禁物です.言語処理系としてのPythonを軽く見ることなく,他の言語を学ぶ場合と同様に(あるいはそれ以上の意識を持って)しっかり学んでいただきたいです.
Pythonは高いレベルの実用性が実証された言語ですので「長いお付き合い」をするつもりで,深い学びに進んでいってください.
written by 中村勝則