質問: 気になったので、初めて質問させていただきます。 プログラミングを初めて一年程度です。 開発予定のサービスをどの言語でするか悩んでいるのですが、Node.jsが速いとネットで読んだので最近ちまちま触ってます。 ふと気になってfor文を100万回ほどしてみたのですが、予想外の展開で驚いています。 比較コードは以下です。 ``` for ( let i=1;i<=1000000;++i ) console.log(i); ``` ``` for ( $i=1;$i<=1000000;++$i ) echo $i.PHP_EOL; ``` ``` for i in range(1000000): print(i) ``` 結果 Node.js 約20秒 PHP 約5秒 Python 約10秒 まだ試してないのですが、Node.jsはシングルスレッドで速いと聞きます。時間があるときに試そうと思っていますが、データベースの接続等はPHPより速くなるものなんでしょうか。websocketなどの導入が比較的簡単だと聞くので、データベースの接続等にのみ限定したほうがよいのでしょうか。 また独学なので比較コードに不備がございましたらご指摘お願いいたします。PHPが一番遅いと思っていたので驚きました。for文のみなのに何か間違いがあるんじゃないかと自分を疑っています(苦笑) 環境 OS: Arch Node.js: v9.8.0 php: 7.2.3 python: 3.6.4
回答: 結論としては、スクリプト言語にそんなに期待しないで下さい。 ネイティブの1/10とか1/20とかそんなもんです。 > > for文のみなのに何か間違いがあるんじゃないか > > > Node.jsが速い・PHPは遅いと良く聞きますし、大まかには私も同意します。 でも、所詮噂であり、言語特性の一面に過ぎないわけですね。 つまり今回のようにfor文とprint文のみで評価すれば別の結果が得られます。 一つの機能だけ取り上げて、言語自体の速度や有用性を語るのはナンセンスです。 なので今回、断片的な情報を元に評価を下す前に質問したのはGJといえるでしょう。 次からは多角的に色々調べてみるようにしてください。 > > Node.jsはシングルスレッドで速いと聞きます > > > その理由はlibuvというC++製のライブラリにあります。 コアの部分のイベントループの仕組みをC言語由来のライブラリでぶん回す事で速度を稼ぎます。 なのでサーバ用途としてはスクリプト言語随一という速度を誇ります。 同期的な処理(for文やconsole.log)の速度自体は大したことありません。 JITコンパイラの最適化を上手く利用すればfor文は加速するのでネイティブ言語に迫れると思いますけど、 console.logは高コストと聞いたことありますね。 今回の不甲斐ない結果は主にconsole.logのせいです。 stdoutを使ってみてください。 > > PHPが一番遅いと思っていた > > > PHPは単純な速度では遅い言語ではありません。 確かに4〜5の初期の時代は処理速度も遅い言語として有名でしたが、 5.0→7.0比で3倍速で動作するようになり、速い言語として認知されています。 メモリのキャッシュヒット率にまでテコが入っており、全てのコードが2倍以上に速度向上を果たしています。 それでもPHPが遅いと言われるのは、ステートレスで動作する設計だからです。 WebサーバのApacheは起動時にPHPのプロセスを4本なり8本なりを同時に起動しておき、 アクセスが来ると対象のindex.phpなりを読み込ませてその時点で初めて実行を開始します。 (Nginx+FastCGI等を利用しても、C10Kに対応出来ない古臭いApacheから脱却出来ただけで、設計思想的な所では変わらず不利です) 他言語のWebサーバはメモリ空間上にやることが全てロードされたプロセスとして準備されます。 「URLがxxなら、この関数(メソッド)を実行してねよろしく」というお膳立てされた状況になるわけです。 PHPはCGI時代の愚直な起動で頑張る設計なんで、いくら走るのが速かろうが他言語に勝てるはずがありません。 しかしTechEmpowerの結果は一般的なスクリプト言語といった順位です。 PHPが持つハンデを考えると、相当チューニングを頑張った高速な言語に見えてくるはずです。 因みにPHPのステートレスな特性ですが、 他の言語は不正なクエリを受け付ける等で例外に遭遇すると、プロセスを巻き込んで全部落ちる可能性があります。 PHPは該当のプロセスしか落ちません。 速度だけならサーバーを複数台建ててロードバランシングで解決しますので、 障害に強いサーバを組みたければPHPが第一候補です。 他の言語もスレッド等を作成して擬似的な別プロセスとして動作させる仕組みがありますので、 設計次第で堅牢なWebサーバは構築出来ますが、PHPのような何も考えずインストールして使うだけで堅牢というのはちょっとしたアドバンテージといえるでしょう。 > > データベースの接続等はPHPより速くなるものなんでしょうか > > > 【修正済】 例えばNode.jsのmysqlライブラリではconnection poolという機能が存在します。 予めMySQLとの接続を5本なり7本なり確保しておいて、 実行していないプロセスを使って通信するというやり方です。 PHPは1接続1プロセスという縦割りの作り方をしています。 持続的接続という機能を使って、 アクセスの度にコネクションが途切れるというわけではないようですが、Node.jsの速度面の設計と比較すると少々貧弱?といった印象ですかね。 Node.jsのように並列処理でSQLをどんどん発行しまくって、 全て揃ったらレスポンスのHTMLを生成するというやり方はPHPでは真似出来ません。 使い方にも寄るものの、Node.jsの方がPHPより速いと思われます。 Pythonに関してはノータッチですのでよく分かりません。 もちろんプロセスを閉じない限りコネクションは張りっぱなしなので、 持続的接続は可能であり、PHPに比べて劣っているという事はないと思います。 > > websocketなどの導入が比較的簡単だと聞く > > > Node.jsはマイクロプロセスをさくっと作る用途に非常に向いた言語で、 WebSocketサーバー等を作るのが非常に得意です。 CommonJS譲りのシンプルな外部ライブラリ読み込みも小気味いい開発速度を誇ります。