JavaScriptやPythonなどの動的言語では、変数の型は実行時に決定されます。これが、Javaなどの型付き言語よりも遅い理由の1つです。
型チェックはどのように実行されますか?このプロセスが遅い本質的な理由は何ですか?
JavaScriptやPythonなどの動的言語では、変数の型は実行時に決定されます。これが、Javaなどの型付き言語よりも遅い理由の1つです。
型チェックはどのように実行されますか?このプロセスが遅い本質的な理由は何ですか?
回答:
質問には混乱があります。
型チェックが遅いという仮定がありますが、必ずしもそうではありません。
また、この質問は、型ディスパッチのプロセスと型チェックを混同しているようです。これらは2つの異なるものです。1つは実行時に行われるプロセスであり、もう1つはコンパイル時に行われるプロセスです。私は質問が本当にタイプディスパッチについて尋ねていると思う。
実行時にオーバーヘッドが発生する可能性があるのはタイプディスパッチです。これは、実行時に表示される値のタイプに基づいて、実行するアクションを動的に決定する命令で計算に時間がかかるためです。たとえば、動的言語では、2つの項目に「+」を適用すると、数値の加算または文字列の連結を意味する可能性があるため、何をすべきかを判断するために手元に目を通す必要があります。動的ディスパッチのコストを削減できる評価戦略があります。(例:JITのトレース)
JavaScriptでの型チェックの実行については、http://www.cs.brown.edu/~sk/Publications/Papers/Published/gsk-flow-typing-theory/を参照してください。型チェッカーの機能のより一般的な概要については、標準のプログラミング言語のテキストでアルゴリズムを説明します。たとえば、http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/
非常に基本的に、型付けされていない言語では、すべての参照は、型と値の両方を含むオブジェクトを指します。たとえばvar a = 3
、値3とint型を含むインスタンスを指します。makeを使用するa = "bla"
と、参照は文字列「bla」と型文字列を含むインスタンスに更新され、古いオブジェクトは破棄されます。
a + b
これらの基本型で操作(たとえば)を行う必要があるたびに、ランタイムは最初にオブジェクトを逆参照し、型の互換性を確認し、操作を実行し、新しいオブジェクトを作成するため、これは低速です。
対照的にa + b
、C ++またはJavaでは、コンパイル時に型が有効で互換性があることを確認し、aおよびbは(参照ではなく)イミディエート値として保存され、追加はこれらの値に対する単純なプロセッサ操作です。
もちろん、これは非常に理論的なものです。実際には、ほとんどのオーバーヘッドを回避するためにこのプロセスで多くの最適化を行うことができ、動的に型付けされた言語は非常に高速になります。