いきなり表題を否定するようだが、実際、Pythonは「遅い」言語だ。
古いデータではあるが、ピーター・ノーヴィック先生もベンチマークを取ってた事がある。
実装にも拠るが、ANSI Common Lispはかなり速い事が分かるだろう。少なくともJavaと同程度には速い(っつーか、これが書かれた時期だと明らかにJavaより速い)。
一方、PythonやPerlはパフォーマンス自体は取り立てて褒めるようなトコはない。平均でC++で同じ事をするのに比較して、Pythonでは20倍程度時間がかかる、と言う事をこの表は言っている。
まぁ、以前言ったけど、こういうのはあくまで「目安」だ。ベンチマークはベンチマークにしか過ぎず、「実用的なプログラムを書こう」としたら「速い言語だと」通常、コーディングに負荷がかかる。そして「安全なプログラム」を書こうとしたら結局実行速度と引き換えになる、ってのがよくある話だ。
Pythonは「遅い」。
ただし、フツーに何かを計算する程度でそれが負担になる事はない。
っつーか、たとえC++で書いたコードの20倍の実行時間がかかろうと、人にとってはそれでも「高速であり」、マトモに、例えばPython「だけで」機械学習の全コードを書こう、とか言う事でもしない限り、そんなにその「遅さ」は気にならない筈なんだ。
んでだな。
Web検索した時、次のような記事を見つけた。
この記事を読んで「う〜む」と考え込んでしまった。
まぁ、端的に言って間違った事を書いている。
そもそも、提示されているPythonコードが酷い。まぁ、言っちゃえばダサいんだ。
これは「Pythonが遅い」んじゃなくって「遅くなるように書いてるだけ」だ。
これじゃ単なる風評被害だ。
この人がダメなんだろうか?
まぁ、本当にこの人がプログラミング初心者かどうかは知らない。
ただ、元ネタを書いた人のPythonコードがダメなんだろう。
生徒が良くても教師がダメならそりゃダメだろ、ってな話だ。
この元ネタを書いた人はクジラ飛行机氏、って人で、日本語プログラミング言語「なでしこ」を開発した人だ、ってのはそのスジの人には知られている。
「日本語プログラミング言語」って事でバカにする人もいるんだけど、それはやっちゃいけない。
少なくとも、以前チラッと書いた事があるけど、「日本語プログラミング言語」と言うのは理論的には、Forthと言うプログラミング言語やPostScriptと言うプログラミング言語の仲間だ。ForthもPostScriptも知名度は低いが(とは言っても「そのスジ」の人間で、特に「PostScript」の名前を聞いた事がない、って人はそれはそれで問題があるぞ・笑)、後置記法の由緒正しいプログラミング言語だ。
そしてそれらはある意味Lispの縁戚だ。Lispは前置記法を一貫して採用してる。Forth、PostScriptは後置記法を採用してる。「なでしこ」は一貫はしてないが、表面的には「後置記法」を採用したプログラミング言語だ。
それはこういう事だ。
足す 1 2 => 前置記法だとこうなる1 2 足す => 後置記法だと語順的に「日本語に見える」
なでしこはここまで単純ではないけど、それでも基本的アイディアはForth/PostScriptなんかの「後置記法」言語の流れを組んだ「由緒正しい」言語システムだ。
クジラ飛行机氏はそういうプログラミング言語を開発した人で、アイディア満載の人なんだろう。それは素直に凄いと思ってる。
ただし、だ。
野球で良く言われてたが名プレイヤーが名監督になれるとは限らない。
それと同じように名プログラマが良い教科書を書くとは限らないんだ。
断っておくけど、僕はクジラ飛行机氏の本を買った事はない。それどころか読んだ事さえない。
しかし、以前、isam氏が「Pythonの教科書」なる本の例題をあげてた事があって、そこで使われてた例があまりにヒドいんでひっくり返ってた事がある。
そう、その「ヒドい本の作者」がクジラ飛行机氏だ。
どのようにその「例題がヒドい」のかはリンク先で説明してるが、いずれにせよ、この例を見る限り、あまり良い教科書を書く人じゃない。例題を一つ見れば大体分かるんだよ。
もう一度繰り返すけど、「ソフトウェア開発者としては」アイディアが優れてる人だと思う。そこは否定しない。
しかし、名プレイヤーが名監督になるとは限らない、って言葉と同じで、「ソフトウェア開発者として良い人」が、「良い教科書を書く」とは限らないんだ。
少なくとも、例を見る限り、この人は度々このブログで批判してる「C言語脳」だ。つまり、「Pythonをキチンと勉強して」Pythonを書いてるわけではなく、「C言語のように」Pythonを書くと言う恐るべき間違いを平気で犯してる人っぽい。
何度も言うけど、個人でプログラミング言語をどんな風に使おうが、そりゃ個人の自由だからどうでもいいんだ。問題はそこじゃない。Python自体を良く知らないのに、プログラミング初心者向けにPythonの本を書くのは間違いだって言ってるんだよ。
分かる?
クジラ飛行机、って人はそれをやっちゃった人だと思う。
もう一回、その元になったコードを見てみよう。
このブログを読んだ事がある人なら、「生粋のPythonista」はこんなバカなコードを書かない、って知ってるだろう。
正しくはこう書くべきだ。
これは10を99に変えようが同じだ。
「一瞬」で「計算」は終わるだろう。そしてIDLEに出てくるSqueezed textっちゅーのは「生成したデータ型」の量が多いんで閉じてるだけ、だ。[右クリック]で[View]を選べばその中身が見れる筈だ。
「実行速度計測」の方法も教えよう。もっともオーソドックスな手は、いつぞやも書いたが、cProfileと言う、プロファイラと呼ばれる類のPython組み込みのソフトを使う事だ。当然 import cProfileして使う。
色々状況によって変わるが(当然)、このワンライナーでのコードの実行時間は僕の使ってるPCだと0.005秒と表示されている。
0.005秒?件のサイトだとRustで書いたコードの実行時間は0.533秒だったと言う。って事はRustで書いたコードの実行時間はPythonで書いたコードの107倍程度時間がかかってる。
つまり、ここでの結論としてはRustはPythonより遅いって事になるわけだ。
もちろんここにトリックが無いとは言わない。
そして最初に書いた通り、僕がPythonが速く実行できるトリックを使ったと言うよりクジラ飛行机氏が元々提示してたコードが「わざと遅くなるように」してるって言われてもしょーがないコードなんだわ。
そして「何も考えない」C言語脳はこういうコードをヘーキで書く。クジラ飛行机氏だけじゃない。
さて、何が問題なのか。このブログを読んでる人は既に気付いてるとは思う。
が、一応解説しておこう。
そもそも、プログラミングに於いて、殆どの場合、「計算」ってのは一瞬で終わる。実は、意外と時間がかかるのは出力の方なんだ。
出力は遅い。これを肝に銘じよう。
映画やアニメでコンピュータの端末が出てくるシーンで、「一文字一文字」順番に表示される、って言う演出が良くある。
こーゆーヤツな。
こんなの90年代でもなくって、当時は今ほどPCが普及してなく、
「こんなんで騙されるのは素人だけだよ!」
とか言って笑ってたモンだが(笑)、実際今でも類似の演出が多い。
これが「皆のイメージするコンピュータ上での端末の動き」で、実際かつてはマジでそうだったわけだ。パソコン以前の話が殆ど、だろうけどな。
言っちゃえば昔のミニコンなんかでも「計算が速く終わっても」端末に「表示する」事の方が時間が取られてた、って事なんだよ。
今だとCPUの計算速度はかつてより遥かに速くなった。しかしながら「表示」に対するタイムラグが「どうしても生じる」ってのは今だ解決していない。殆どのケースだとAcceptableなんだけど、特にインタプリタへの「出力」ってのは端末に対する出力、より一般には時間がかかるようだ。
そう、件のプログラムで遅くなってる最大の原因はとにかく出力する、と言う悪しきスタイルだから、だ。計算が遅いわけじゃない。
事実、Rustのプログラムでさえ、0.533秒も時間がかかってる・・・1秒の半分も、だぞ?のも出力ばっかしてるから、なんだよ。
こういうスタイルは悪いスタイルのプログラムなんだ。でもC言語脳はこういうしょーもないプログラムをヘーキで書く。
Pythonなんかのモダンなプログラミング言語(あるいはRustでさえも)では、何度も言ってるけど、まずは出力せずにデータ生成をする、と言うのが正しい考え方だ。一方、なんでもかんでも出力せな、ってのはC言語脳の悪しき考え方なんだ。
僕が提示したプログラムは特に出力してない。別にprintせずともIDLEみたいなインタプリタ上なら簡単に結果が確認できるから、だ。
言い換えれば「計算だけしてる」んで速いんだよ。不必要な事をしない、ってのが高速な理由であって、これは(僕は違うが)「生粋のPythonista」なら皆知ってる事だ。「不必要な出力は避ける」ってのがモダンな言語だと当たり前の考え方なんだ。
分かるだろうか?プログラミングスタイル、ってのは非常に重要で、言語設計に準じた考え方でプログラムせぬ限り遅くなる場合もあり、それを知らないで、「速い」とか「遅い」とか言っても意味がないんだ。
あるプログラミングスタイルがその特定の言語に「合ってる」とか「合ってない」かがプログラムの実行速度の「速い」「遅い」に影響する良い例、だと思う。単純に「Rustが速い」とか「Pythonが遅い」とか言ってる「だけ」じゃ意味がないんだよ。
そしてC言語脳は「C言語は全てのプログラミング言語の基礎だ」と言うしょーもない盲言を信じてる。事実は違って、これも何度も言ってるが、「抽象度の高いプログラミング言語」はそれより抽象度が低い言語の書き方を全て受け入れてしまうだけ、だ。でもそれは「その言語に於いて望ましいプログラミングスタイルだ」と言うわけではない。
少なくともこんなコードをプログラミング初学者に出す以上、クジラ飛行机氏は単にPythonに於いては勉強不足だ、って事だ。
そして「Rustの構文が一見Cに似てて」、C言語っぽく書けばRustを使える、なんて考えてるのならまた初学者を大間違いに誘ってる、とは言えるだろう。
まぁ、僕はそこまでRustは知らん。ただし、感触的にはRustはかなり関数型言語からアイディアを取っているって事は知っていて、それで言うと「C言語のようにRustを使う」のならあまり良い結果は産まないだろう。
ちなみに、関数型言語の雄、HaskellユーザーからもRustは割に良い評価を得ている。それは構文スタイルはともかくとして、機能的にはたくさんのものを関数型言語から持っていってるからだ。
C言語脳はこのテの「機能」をほぼ知らない。Pythonでこれだけ勉強しない人が果たしてRustなら勉強するのか?とかなり疑ってかかってる僕がここにいる。
まぁ、補助教材としてクジラ飛行机氏の本を使ってもいいだろう。ただし、Rustを本当にキチンと使いたいのなら、やっぱThe Bookを読むべきじゃないの?と思う。前にも書いたけど、日本の本って結果、ダメなんだよ。
そしてプログラミング言語の「仕組み」をそこまで知らないのなら、簡単に「速い」とか「遅い」とか言うべきじゃないと思う。
じゃないと、ここで見たように「とんでもない間違い」を書くだけ、だから。
当然、例にあげたようなプログラムはとてもじゃないがベンチマークなんかには使えない。