質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.91%

Node.js, PHP, Pythonでforを回したときの速度

解決済

回答 5

投稿

  • 評価
  • クリップ 2
  • VIEW 8,441

Newbi

score 162

気になったので、初めて質問させていただきます。
プログラミングを初めて一年程度です。

開発予定のサービスをどの言語でするか悩んでいるのですが、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

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

checkベストアンサー

+12

結論としては、スクリプト言語にそんなに期待しないで下さい。
ネイティブの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譲りのシンプルな外部ライブラリ読み込みも小気味いい開発速度を誇ります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/18 09:22

    PHPでも、DB接続についてはPHPの側で使い回す「持続的接続」があります。

    http://php.net/manual/ja/features.persistent-connections.php

    キャンセル

  • 2018/03/18 09:30

    おお、これは知りませんでした。
    PDOでも使用出来るんですね!
    http://php.net/manual/ja/pdo.connections.php

    これ、コネクションプール5本張って開いてるコネクションを優先的に使うNode.jsと比べてどうなんでしょうね?
    1本のコネクションを複数プロセスが使いまわそうとして順番待ちみたいになってあまり速度が稼げない可能性も考えられたりします。
    (私の調査不足により)動作がまだよく分かってないので、一応回答文は既存のままにしておきます。

    キャンセル

  • 2018/03/18 09:53

    現時点で分かってる内容を元に、嘘になってた箇所を修正しました。
    ありがとうございました!

    キャンセル

  • 2018/03/19 02:47

    ご回答ありがとうございました!
    Node.jsの出力をprocess.stdout.writeで行ってみたら、数値は出力できず文字列にはなったものの、5秒ほど短縮しました!
    またネットでたまたま見かけた比較コードで、バブルソートを行う記事を見つけました。それを試してみたところ、単純なfor文のみではPHPが最速だったものの、バブルソートではGo言語が圧倒的に最速で、Node.js、PHPの順になりました。それを受けて少し調べながら、各言語の得意不得意を意識してPHPとGoでforを回してみたところ、出力なしの場合、圧倒的な差が開くことが分かりました。また出力する場合でもGoは単純な連結でなくbufferで行うなど工夫が必要なことを痛感しました。
    サーバーとの関係に関してもまだまだ不十分なので、しっかり勉強しようと思います。
    ありがとうございました!

    キャンセル

+9

ふと気になってfor文を100万回ほどしてみたのですが、予想外の展開で驚いています。

Node.jsのconsole.logは、環境・状況によってはブロッキングな書き込みとなる(バッファリングされない)ため、他の言語より不利となることがあります(Node.js公式)。実運用のパフォーマンスとは直接関係しません

ただ、Node.jsでRDBMSを扱おうとすると、取得処理などもすべてが非同期となるので、async^awaitなどを使いこなせなければかなり煩雑となります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/19 03:02

    ご回答ありがとうございました!
    今までPHPと、javascriptはフロント側を少し触る程度だったので(ajaxもjquery)、Node.jsを触ってみてまたけっこう勉強がいると思いました。でも少し触っただけですが、とても便利です。
    PHP, Node.js, Goをいま検討しているので、Node.js、Goをそれなりに書けるようにしてからどの言語にするか決めたいと思います。
    ありがとうございました!

    キャンセル

+7

論点がずれるかもしれませんが、回答させていただきます。

そもそも開発言語の選定はパフォーマンスだけで決めるのは厳しいと思います。

自分がもし選定するのであれば、例えば以下のような観点から考えます。(他にもあるかもしれませんが、ぱっと思いつくところで)

  • 将来的にメンテナンスし続けられる体制が構築できる言語か?

周りの開発者の学習コストも加味したほうがいいです。サービスの継続性を考えるのであれば、周りの開発者の協力が不可欠ですので。あと言語だけでなくフレームワークも考慮したほうがいいかもです。言語だけでなくどんなフレームワークがあるかも調べたほうがいいかもです。

  • 開発しようとしているサービスに必要なライブラリが揃っているか?

だいたいどの言語もライブラリは充実していますが、例えば機械学習であればpythonが一歩飛び抜けていたりします。

  • 開発しようとしているサービスがどの程度パフォーマンスを要求するか?

大規模サービスでも使っている言語は多様であるため(大手サービスがPHPを使っているなんてことはザラです)、特殊なパフォーマンス要件が無ければどの言語でも大差は無いのではないでしょうか。むしろ言語でなくそれを取り巻くWEBサーバやデータベース、アーキテクチャー等の選定のほうが重要かもしれません。

参考までにどうしてもパフォーマンスが気になるのであれば、以下記事が参考になります。
Qiita

もしこちらの質問で明確に言語の提案が欲しいのであれば、開発予定のサービスが具体的にどのようなものか質問に記載いただけると、より多くの回答が集まるのではないでしょうか。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/20 03:09

    PugとSlimを調べてみました!
    すごいですね! 「HTML SCSS」や「HTML 効率的に」など検索しても大して見つからなかったので、自作してたんですが、ほぼ同じのがもうあったとは。。
    素じゃないHTMLというのは、PugやSlimのことでよろしいのでしょうか? それとも他に、もっと効率的なツールがあるのでしょうか。

    リアルタイム処理はメッセージ機能(チャット)に必要なためwebsocketを検討しています。ajaxで短い間隔で更新して試してはみたんですが、感覚を短くするとパフォーマンスが悪く、長くするとリアルタイム性に欠ける点がありました。調べたらポーリングというらしく、ロングポーリングという方法も見たんですが、websocketなどがいいらしいので、一度試してみようと思っています。サーバー側からプッシュしてくれるものと理解しています。ajaxのみの実装で実現できたら一番楽なのですが。またその他の機能でもおそらくけっこうな頻度でサーバーに繋いだり、アクセスも見込めるため、できるだけ捌ける方法を模索中です。
    いつもPHP+Apacheで特に目新しいものはなかったんですが、今回は色々試したくて勉強しています。
    色々検討しようと思います。

    キャンセル

  • 2018/03/20 09:34

    > 素じゃないHTML
    もっとPHPならではのMySQLにクエリ投げて、その結果を元にHTMLを動的に生成する行為を指します。
    PugやSlimをPHPやNode.jsのテンプレートエンジンとして利用する方法もありますが、
    普通に使う場合、一回素のHTMLを生成し、その生成したHTMLを本番環境にアップロードする流れになります。
    つまり、素のHTMLを生成した時点で、表現力は素のHTMLと同等まで落ちてしまいます。

    これを指して、(PugやSlimをHTMLに変換掛けると)素のHTMLになりますが、これで足りていますか?
    …という質問をしていました。

    まぁ、SPA(シングルページアプリケーション)という手段まで行けば、
    データ部とフロントエンドが完全に切り離されるので、SEOを考えなければどんな構造のページも表現仕切れます。

    > リアルタイム処理
    それならWebSocketですかね。
    でもGoやElixirみたいなスレッド作るのが上手い言語を採用すれば、Ajaxでも結構がんばれますよ。
    1アクセスが数msどころかnsレベルの単位になりますからね。

    WebSocketはスマホの画面をオフにした時等のイレギュラーな状況が少し弱いので、
    色々テストを重ねて検討してみてくださいね。

    キャンセル

  • 2018/03/21 02:42

    なるほどですね。Ruby(Rails)のSlimはとても便利そうですが、いったんHTMLに戻すのでは少し役不足ですね(解釈合ってますよね汗)
    RailsでSlimをコンパイルせずに使える? と見たのですが、PHPでそこまでよさげなのは見つかりませんし(PugでPHPを組み込むみたいな記事は見ました)、Rubyで作っても良いんですが、いったんNode.js,、Goをだいたい書けるようにして、Rubyも検討してみたいと思います。

    SPA、と言うんですね! 開発予定のサービスもこの形になる予定です!(笑)
    SPAで調べたら事例にFacebook等が出ましたが、思ったよりこういう作り方はあったんですね。SEOとの兼ね合いで色々悩んでいたんですが、少し後押しをいただけました。

    Goちょっと触ってみてとてつもなくびっくりしてるところです!
    PHPと違い、javascriptとも違い、新しく勉強を初めてなかなか苦戦中です笑
    PHPでも型をそれなりに気をつけていたつもりでしたが、Goはなかなか厳しいです。Javaなどもいずれしてみたいとは思ってるんですが、少し心配になるくらいです(笑) コンパイルエラーで怒られまくりです。
    でも速度は圧倒的ですね。比較が正しいかは分かりませんが、今のところ、今後必要とするもので(高度な計算などはないので)MySQLのselectやinsertなどで色々比較をしてみています。今後検証をもっと重ねてみて決めようと思います。

    「websocket バグ」「websocket エラー」などで検索したらそこそこ出てきますね。。
    スマホはUI等を考えるのは好きなんですが、書くのも嫌いではないんですが、いつも気が重いです。
    色々と調べながらがんばってみようと思います。

    親切にアドバイスをくださってありがとうございます!
    現在絶賛Goでハマり中なので、また色々お世話になるかもしれませんが、今後ともよろしくお願いいたします。
    いつもteratail見てるんですが質問したことはなかったので勉強になりました!

    キャンセル

+3

PHPが遅いなんてのは遥か昔のイメージで
PHP7以降は相当速くなってる。

そもそも高速化はサーバー側でどうにかしてるのでもはや言語はなんでもいい。
動的型な時点で全部同じようなもの。

本当に速度が欲しい場合はコンパイルする言語が必要になる。
なんとなくGoが流行ってる気がするのはこの辺りで非常にちょうどいい落とし所だから。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/19 03:08

    ご回答ありがとうございました!
    Go言語を少しだけ触ってみました。HTML, CSS, javascript, PHPというまあホームページに必要なものから入ったので、Goを含めサーバーサイドで動く言語をいくつか触ってみてとても新鮮に感じているところです。
    速度的にはGoが最速だと思います。後は私がどこまで書けるのか、また欲しい機能をどこまで実装できるのか探っていきたいと思います。
    ひとまずはNode.js、Goのどちらもそれなりに書けるようになってから決めることにしました。
    勉強してみます。
    ありがとうございました!

    キャンセル

+1

文字出力を繰返すのは、速度比較としてはあまり適切ではないです。
装置とのやりとりは計算処理処理よりは時間がかる処理だからです。

文字列を表示するかわりにプリンタへの印刷にしたら、言語の処理速度でなく、
プリンタの印刷速度の計測になってしまうでしょう。

参考

...
c          real:3.68[sec]
javascript real:4.94[sec]
node       real:4.94[sec]
python     real:3.93[sec]
ruby       real:16.90[sec]
...

もちろん この数値だけで評価してはいけません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/22 00:45

    ご回答ありがとうございます!
    速度比較については多角的に行うことを他の方にもアドバイスいただいたので、現在Goを触りながらちまちまと進めているところです。ただ、比較についていまいち判然としなくなっている部分もあります。
    ライプニッツ級数の記事も以前見たので、手元の環境でも実行してみました。すると確かに、GoよりJavascriptが速く終わりました。
    一方で、
    https://jaxbot.me/articles/benchmarks_nodejs_vs_go_vs_php_3_14_2013
    こちらではバブルソートを行い、Goが速く終わりました。
    計算処理はJavascriptが速く、配列操作など単純な操作はGoが速いのかなと判断しています。
    こういった部分を踏まえた上で、私の用途はMySQLとの接続や配列処理がメインになるため、いまはselectやinsert、置換や分割等、基本処理をそれぞれ比較してみています(高度な計算は行わないので、用途の範囲内で速い方を選べればということで)。
    しかし、やっぱりライプニッツ級数とバブルソートの速度差はとても気になっています。。
    私の比較コードが正常に比較できていなかったのは理解したのですが、この2つなど、Javascript、Goでそれぞれ得意とするところ、そしてどちらが本当に速いのか、というのがいまいち判然としていません。Node.jsのイベントループやGoの並列処理のメリットなどはよく見かけるのですが、単純な速度に関しては少ないような気がします。Goが速い、と書いている記事自体は多いのですが。Node.jsが速い、という記事もあります。
    速度に関して一概に言えないことは理解しているのですが、今後の勉強のためにも少し気になっています。
    単純な処理はGoが速いので(重い計算はしないため)、今回はGoを考えようかなと思ってはいますが、できる限り情報と比較結果を集めてから判断するつもりです。
    そのうち、きちんとお見せできるような比較コードが書けたらまたこちらで相談させていただくかもしれません。

    ちなみに、プリンタの印刷速度というのが少し分かりませんでした。それぞれの言語仕様で出力の速度が異なる、というのは理解したのですが、プリンタの例えですと実行環境のスペックによる、ということなのかなと解釈しました(間違っていたらすみません汗)
    後もうひとつの解釈で、それぞれの言語で出力と計算は別で、出力は言語処理とは言い難い、という感じかなと思いました。

    解釈が間違っていたら申し訳ないのですが、比較は今後回を重ねてできるだけ多角的にがんばりたいと思います。
    またこちらでお世話になるかもしれませんが。。笑

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る