アカウント名:
パスワード:
ネイティブなマシン語なら当たり前だよね?あとは最適化とかライブラリの出来次第。実際には多少遅くとも同等扱いなんでしょ。
> ネイティブなマシン語なら当たり前だよね?
それは良くある勘違いです.当たり前ではありません.
C/C++のコードに比べるとpythonのコードはコンパイル&最適化が難しいです.難しい理由の一つは,pythonは実行するまで変数の型が決まらないためです.これはネイティブなマシン語を吐くだけでは全く解決できない問題です.
C/C++ふうに言えば,pythonでソースコード中に foo(x) という関数呼び出しがあった場合xの型はint型,unsigned int型,float型,std::string型,struct X,class Y,など無限の可能性があります.当然実行時には型の候補は有限で,実際の型は実行時には一つになります,ただし実行されるたびに型が変わる場合もあります.だからpythonインタプリタは実行時に毎回型チェックをやって,その都度CPUが実行するコードを切り替えています.ですから,仮に全パターンのマシン語を生成して,それを実行時に切り替えたところで,CPUの命令キャッシュがぐちゃぐちゃになるだけで何も問題は解決しません.
これは実行時の問題なので,実行時コンパイル(JIT)を使わないと解決できません.つまり直接マシン語を吐く古典的方法ではなく,バイトコードをはいてバイトコードを効率よく実行する仕組みを別途用意する現代的方法で解決します.
しかしまだその技術は確立されていません.だから現状のpythonは実行速度はまだ遅く,高速化の研究が盛んに行われているのです.
言い換えると,まだ当たり前の域には到達してないから,python の処理系には伸びしろがあります.たとえば2022年10月にリリースされたPython 3.11は 3.10に比べて10~60%高速になってます.3.11の高速化はまさに上記のバイトコードを効率よく実行する仕組みの改良でhttps://github.com/markshannon/faster-cpython [github.com] の成果です.このプロジェクトの中の人たちも,まだ伸びしろがあると言っています.
ここで注意すべきは,pythonはバージョンが3.11まで進んでるのに,これからも性能向上が見込める点です.それくらい今のpython処理系はクソなのです.
>それくらい今のpython処理系はクソなのです.処理系というか、言語仕様からの"実行"の難しさだよね。それを分かったうえで、木に竹を接ぐようなことをしている。やっている連中は面白いからやっているのだろうけど、まったく筋が悪いことをやっているような気がするけどx86アーキテクチャと同じでそこにニーズがあるからやっていられるんだろうなぁこんなことまあ、袋小路に入らないで行き着く先を見てみたいですけどね。
言語比較のベンチマークで非jitのluaが馬鹿みたいに速いのはなんでだろう。勝っているのがluajitぐらいなのが不思議でならない。
他のVMが基本的にスタックマシンなのに対し、Lua VMはレジスタマシンになっているから、という説明は見かけるね。複合データ型も配列(連想配列)だけに特化して、今どきっぽいモノはシンタックスシュガーでごまかすことで、内部処理を最適化しているように見えます。何より、処理系が小さいので今どきのx86だとキャッシュがよく効くということもあるかも。
わざわざ向いていないことをどうにかしようとするために時間を割くよりは向いていることをやったほうがいいよ。
実行速度を求めるならRustで書けばいいとおもうのよね。
> 当然実行時には型の候補は有限で,実際の型は実行時には一つになります,ただし実行されるたびに型が変わる場合もあります.
型推論が重いのは事実だが、アルゴリズム自体は30年前にselfコンパイラで提案されている。
整数オーバーフロー検出も、実行時プロファイルのAOTコンパイラへのフィードバックと値範囲解析とCPUの投機実行により、オーバーフローしなかったパスの速度低下はかなり~完全に抑えられる。これも20年くらい前からある技術。
Cythonとかはその路線。Pythonはあくまでもアノテーションはアノテーションでアノテーションと実際に入ってきた値で実際に入ってきた値を採用する。
別におかしなことを書いてるわけではないんだけど、
> アノテーションは アノテーションで アノテーションと> 実際に入ってきた値で 実際に入ってきた値を
ちょっとクラクラしたw
しかしC言語は「整数オーバーフローしたときの動作は未定義です」(=コンパイラーは整数オーバーフローが発生したときのことを一切考えなくていい)というチートを繰り出すからそれでも勝てないんだよな
「ほとんどの場合はワード長におさまるが、たまにオーバーフローして多倍長整数で計算しなければならない」ような場合ならPythonが有利になります。Cだとオーバーフローの検出ができないので、ソフトウェア的に判断するか、最初から多倍長で計算するしかない。
ソフトウェア的に判断すると言ってもそれはPythonの言語機能がやっていることと同等以上だからそれをもってPythonが有利と言われても意味不明ですね。むしろPythonは必要がなくてもそのチェックを外せない
たとえばx86にはオーバーフローフラグがあって、整数演算でセットされるから、次の命令で条件分岐するだけです。PyPyもそうしている。意味不明に思えるのはただの無知。加算がオーバーフローしうるならadd eax,edxjo _handle_overflow_and_switch_to_bignum高頻度パスには条件分岐だけ付け加えればよくて、これは投機実行でコストはほぼ0になる。ごく単純な仕組みだが、Cは言語レベルではオーバーフローを扱えないので生成不可能なコードになる。
>> Cは言語レベルではオーバーフローを扱えないので生成不可能なコードになる。
ずいぶん言語拡張されてるんだからオーバーフローで分岐できるような記述を追加すればいいのにね。構造化アセンブラなんて言われ方も有るんだし。
add eax,edxjo _handle_overflow_and_switch_to_bignum... ; use eax高頻度パスがこうだとすると、オーバーフローハンドラは「オーバーフローしうる演算」それぞれと一対一で用意しますが、コードサイズは大きくなく、所詮一回しか実行しません(どれかが一つオーバーフローすると、全体をbignumで処理するコードに切り替えます)。オーバーフローしたという情報と、それを起こした演算についての知識から、正しい演算結果をbignumで構成することができます。x86なら乗算結果はedx:eaxに入ります(x64も同様)。それからbignum版のルーチンに移行して、戻ってきません。
配列のインデックスなどはvalue range analysisという古くからある技術で、ワードに収まることがわかる場合がほとんどです。たとえばポインタと加減算するための値なら、決してオーバーフローはしません。これは大域的な解析なのでコンパイルは重くなります。
追加すれば良いも何も、c23でstdckdint.hが追加されてるだろ。
実行時でなけれ型が決まらないということは、コンパイル時の静的な型チェックがかからないということそういうたぐいのプログラミング言語は用途によっては危なっかしくて困る今の時代はクラシックなPascalなんかのご利益を理解出来ないソフト屋さんが多いのは残念
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
開いた括弧は必ず閉じる -- あるプログラマー
C/C++と同等もしくはそれ以上の性能 (スコア:0)
ネイティブなマシン語なら当たり前だよね?
あとは最適化とかライブラリの出来次第。
実際には多少遅くとも同等扱いなんでしょ。
Re:C/C++と同等もしくはそれ以上の性能 (スコア:5, すばらしい洞察)
> ネイティブなマシン語なら当たり前だよね?
それは良くある勘違いです.当たり前ではありません.
C/C++のコードに比べるとpythonのコードはコンパイル&最適化が難しいです.
難しい理由の一つは,pythonは実行するまで変数の型が決まらないためです.これはネイティブなマシン語を吐くだけでは全く解決できない問題です.
C/C++ふうに言えば,pythonでソースコード中に foo(x) という関数呼び出しがあった場合
xの型はint型,unsigned int型,float型,std::string型,struct X,class Y,など無限の可能性があります.
当然実行時には型の候補は有限で,実際の型は実行時には一つになります,ただし実行されるたびに型が変わる場合もあります.
だからpythonインタプリタは実行時に毎回型チェックをやって,その都度CPUが実行するコードを切り替えています.
ですから,仮に全パターンのマシン語を生成して,それを実行時に切り替えたところで,CPUの命令キャッシュがぐちゃぐちゃになるだけで何も問題は解決しません.
これは実行時の問題なので,実行時コンパイル(JIT)を使わないと解決できません.
つまり直接マシン語を吐く古典的方法ではなく,バイトコードをはいてバイトコードを効率よく実行する仕組みを別途用意する現代的方法で解決します.
しかしまだその技術は確立されていません.だから現状のpythonは実行速度はまだ遅く,高速化の研究が盛んに行われているのです.
言い換えると,まだ当たり前の域には到達してないから,python の処理系には伸びしろがあります.
たとえば2022年10月にリリースされたPython 3.11は 3.10に比べて10~60%高速になってます.
3.11の高速化はまさに上記のバイトコードを効率よく実行する仕組みの改良で
https://github.com/markshannon/faster-cpython [github.com] の成果です.このプロジェクトの中の人たちも,まだ伸びしろがあると言っています.
ここで注意すべきは,pythonはバージョンが3.11まで進んでるのに,これからも性能向上が見込める点です.それくらい今のpython処理系はクソなのです.
Re: (スコア:0)
>それくらい今のpython処理系はクソなのです.
処理系というか、言語仕様からの"実行"の難しさだよね。
それを分かったうえで、木に竹を接ぐようなことをしている。
やっている連中は面白いからやっているのだろうけど、
まったく筋が悪いことをやっているような気がするけど
x86アーキテクチャと同じでそこにニーズがあるからやっていられるんだろうなぁ
こんなこと
まあ、袋小路に入らないで行き着く先を見てみたいですけどね。
Re: (スコア:0)
言語比較のベンチマークで非jitのluaが馬鹿みたいに速いのはなんでだろう。
勝っているのがluajitぐらいなのが不思議でならない。
Re: (スコア:0)
他のVMが基本的にスタックマシンなのに対し、Lua VMはレジスタマシンになっているから、という説明は見かけるね。
複合データ型も配列(連想配列)だけに特化して、今どきっぽいモノはシンタックスシュガーでごまかすことで、内部処理を最適化しているように見えます。何より、処理系が小さいので今どきのx86だとキャッシュがよく効くということもあるかも。
Re: (スコア:0)
わざわざ向いていないことをどうにかしようとするために時間を割くよりは
向いていることをやったほうがいいよ。
実行速度を求めるならRustで書けばいいとおもうのよね。
Re: (スコア:0)
いい内容の書き込みだなぁと思いながら読んでたのに、これで全て壊された。
Re: (スコア:0)
> 当然実行時には型の候補は有限で,実際の型は実行時には一つになります,ただし実行されるたびに型が変わる場合もあります.
型推論が重いのは事実だが、アルゴリズム自体は30年前にselfコンパイラで提案されている。
整数オーバーフロー検出も、実行時プロファイルのAOTコンパイラへのフィードバックと値範囲解析とCPUの投機実行により、オーバーフローしなかったパスの速度低下はかなり~完全に抑えられる。これも20年くらい前からある技術。
Re: (スコア:0)
Re: (スコア:0)
Cythonとかはその路線。
Pythonはあくまでもアノテーションはアノテーションでアノテーションと実際に入ってきた値で実際に入ってきた値を採用する。
Re: (スコア:0)
別におかしなことを書いてるわけではないんだけど、
> アノテーションは アノテーションで アノテーションと
> 実際に入ってきた値で 実際に入ってきた値を
ちょっとクラクラしたw
Re: (スコア:0)
しかしC言語は「整数オーバーフローしたときの動作は未定義です」(=コンパイラーは整数オーバーフローが発生したときのことを一切考えなくていい)というチートを繰り出すからそれでも勝てないんだよな
Re: (スコア:0)
「ほとんどの場合はワード長におさまるが、たまにオーバーフローして多倍長整数で計算しなければならない」ような場合ならPythonが有利になります。Cだとオーバーフローの検出ができないので、ソフトウェア的に判断するか、最初から多倍長で計算するしかない。
Re: (スコア:0)
ソフトウェア的に判断すると言ってもそれはPythonの言語機能がやっていることと同等以上だからそれをもってPythonが有利と言われても意味不明ですね。むしろPythonは必要がなくてもそのチェックを外せない
Re:C/C++と同等もしくはそれ以上の性能 (スコア:1)
たとえばx86にはオーバーフローフラグがあって、整数演算でセットされるから、次の命令で条件分岐するだけです。PyPyもそうしている。意味不明に思えるのはただの無知。
加算がオーバーフローしうるなら
add eax,edx
jo _handle_overflow_and_switch_to_bignum
高頻度パスには条件分岐だけ付け加えればよくて、これは投機実行でコストはほぼ0になる。
ごく単純な仕組みだが、Cは言語レベルではオーバーフローを扱えないので生成不可能なコードになる。
Re: (スコア:0)
>> Cは言語レベルではオーバーフローを扱えないので生成不可能なコードになる。
ずいぶん言語拡張されてるんだからオーバーフローで分岐できるような記述を追加すればいいのにね。
構造化アセンブラなんて言われ方も有るんだし。
Re:C/C++と同等もしくはそれ以上の性能 (スコア:1)
add eax,edx
jo _handle_overflow_and_switch_to_bignum
... ; use eax
高頻度パスがこうだとすると、オーバーフローハンドラは「オーバーフローしうる演算」それぞれと一対一で用意しますが、コードサイズは大きくなく、所詮一回しか実行しません(どれかが一つオーバーフローすると、全体をbignumで処理するコードに切り替えます)。
オーバーフローしたという情報と、それを起こした演算についての知識から、正しい演算結果をbignumで構成することができます。x86なら乗算結果はedx:eaxに入ります(x64も同様)。それからbignum版のルーチンに移行して、戻ってきません。
配列のインデックスなどはvalue range analysisという古くからある技術で、ワードに収まることがわかる場合がほとんどです。たとえばポインタと加減算するための値なら、決してオーバーフローはしません。これは大域的な解析なのでコンパイルは重くなります。
Re: (スコア:0)
追加すれば良いも何も、c23でstdckdint.hが追加されてるだろ。
Re: (スコア:0)
実行時でなけれ型が決まらないということは、コンパイル時の静的な型チェックがかからないということ
そういうたぐいのプログラミング言語は用途によっては危なっかしくて困る
今の時代はクラシックなPascalなんかのご利益を理解出来ないソフト屋さんが多いのは残念