多くの場合、特定のタスクに特化したプログラミング言語があります。一部のプログラミング言語は、配列演算(マトリックスや多次元配列の使用など)に優れていますが、一部のプログラミング言語は、他の言語で再現するのが難しい高レベルの数学に優れています(それでもなお可能です)。
とにかくアセンブリに至るまで最も単純にコンパイルされることを考えると、ある言語は他の言語よりも特定のタスクまたは最終目標に対してそれを改善しますか?
私はチューリング完全な言語、チューリングと同等の言語について話している。
多くの場合、特定のタスクに特化したプログラミング言語があります。一部のプログラミング言語は、配列演算(マトリックスや多次元配列の使用など)に優れていますが、一部のプログラミング言語は、他の言語で再現するのが難しい高レベルの数学に優れています(それでもなお可能です)。
とにかくアセンブリに至るまで最も単純にコンパイルされることを考えると、ある言語は他の言語よりも特定のタスクまたは最終目標に対してそれを改善しますか?
私はチューリング完全な言語、チューリングと同等の言語について話している。
回答:
考慮すべきことがいくつかあります。
抽象化:言語は「特別」として何を扱いますか?Matlabのように、行列はファーストクラスの値ですか、それともCなどの配列のような単純な型を使用してエンコードしますか?Cは、マトリックスの実装方法を考えさせますが、Matlabは考えません。
同様に、非同期通信の複雑なシステムがある場合は、コールバックを実行できるように、おそらくファーストクラスの関数が必要です。
追加される機能が多いほど、言語は複雑になります。そのため、C ++やDのような「マルチパラダイム」言語がいくつかありますが、ほとんどの言語はニッチを選択し、そのニッチにとって重要なものを選択し、それらを主要な抽象化として優先します。
パフォーマンス:コンパイル時でも実行時でも、すべての抽象化にはコストがかかります。一部の言語は、抽象性が低くなり、パフォーマンスが向上するように制限されています。
初期のFortranでは、ポインターや再帰を許可していなかったため、多数のループを実行しているCのような言語よりも高速で、数値計算に優れていました。しかし、インダイレクション用のポインタが必要なツリーのような大きなデータ構造のエンコードはひどいものでした。(現代のFortranについてはあまり知らないことに注意してください。)
基本的に、常にトレードオフがあります。抽象度が高いとは、ランタイムが遅いか、コンパイル時に複雑さが増すことを意味します。より多くの機能は、より複雑な言語を意味します。ポインターや再帰のように、特定の機能を高速化する機能と低速化する機能があります。完璧な言語はないので、各言語は言語の質の面で一種の極大に達します。
一部の言語の制約により、より高速なコード(FortranとCおよびポインターのエイリアシングなど)の実装が容易になります。これは、すぐに使用できるパフォーマンスと可能性のトレードオフです。
この言語は特定のタスクに対して「最適化」されていませんが、コンパイラーによるコードの理解を容易にする実装、コンパイラー、および制約がそうします。本当の問題は特定のライブラリについてであり、問題の長さに応じてスイッチを使用してプロセスを高速化するために実装されたアルゴリズムが最適化されます。
たとえば、乗算ではさまざまなケースが使用されます(GMP乗算を参照)。
言語が高レベルの数学演算を指定する場合、その実装は最適です(この場合は効率的)が、それは言語仕様の一部ではありません。
Matlab、MathematicaおよびMapleでの行列ランクの計算を見てください(今のところすべてのテストを自分で実行することはできませんが、これらはテストと一致しています)。これらのすべての言語(環境)は同じ高レベルの操作を実装しますが、実装の詳細は異なるため、さまざまな時間が与えられます。
いくつかのドメイン固有のタスク(ここではドメイン固有の言語)が特定の計算に向けられている場合、ターゲットオーディエンス向けに(長年にわたって)改善および最適化されます。しかし、常に最適であるとは限りません。たとえば、Perlには文字列処理の長い歴史がありますが、PCRE(ここでは単にPerlの正規表現)は既存の最速のものではなく(そして大量のメモリを使用します)、非常に表現力があり強力です。
言語の制約により、コンパイルプロセスに違いが生じます。前述のポインターエイリアシングは、コードの並べ替えの可能性を防ぎ、変数の再読み込みを強制します。
私の意見では、これは実際に非常に正確に定式化できます:ツール(たとえば、プログラミングライブラリとその標準ライブラリ)は、使用可能なすべてのツールを最小化するとき、特定のクラスの問題に最適なツールです。問題クラス内のすべての問題に対する特定の確率分布に対する期待が十分に得られる、十分に正確でパフォーマンスの高いソリューションを得るための予想コスト。ほとんどの場合、このコストはプログラマー時間の形で発生し、予想される設計時間、予想されるデバッグ時間、ツールにまだ慣れていない人の教育に必要な予想時間などが含まれます。
実際には、これらの量のほとんどは実際には測定できません。それでも、私はそれが問題について考える正しい方法だと思います。
それは素晴らしい質問であり、簡単に答えられません。Erlang言語について、リアルタイム通信アプリケーションに適したものはありますか?それとも、Erlangコンパイラに関するものですか?それとも、Erlangコミュニティとエコシステムに関するものですか?おそらく、テレコムアプリケーションの作成方法を知っている人はErlangの専門家であり、Erlangを知っている人はテレコムアプリケーションの専門家でしょうか?これらすべての要因が役割を果たしていると思います。
Erlangには、おそらくそのようなアプリケーションに適した2つの機能があります(注意:自分でこの言語を使用したことはありません)-並行性と動的ソフトウェアアップグレードのサポートが良好です。これらの機能は他の多くの分野でも役立ちますが、テレコムエンジニアは稼働時間に夢中です。おそらく、Webサイトを構築する人々が電話交換を構築する人々と同様に高可用性を懸念しているのであれば、Erlangもそこで人気があるでしょう。
他の答えは、特定のタスク用に言語を最適化するという点を見落としています。それは、特定のハードウェアでコードを高速に実行する理由だけではありません。特定の言語がいかに明確かつ簡潔に問題の解決策を表現できるかということです。それは問題の領域に大きく依存し、(マーケティングの誇大広告、既存のソリューションの無知、新しい言語を書く自我の旅と一緒に)私たちが複数の言語を持っている理由です-目標はプログラマがより少ないコードを書くことですエラーが発生しにくく、次のプログラマーが読みやすく、理解しやすく、修正しやすく、改善しやすくなります。
たとえば、CとC ++の両方をオブジェクト指向プログラミングに使用できます。実際、GObjectライブラリはOO Cの良い例です。関数ポインターを含むAC構造体は、C ++クラスの仮想メソッドと同じ目的を果たし、実行できます。より良い; 開発上のペナルティは、メモリを割り当て、関数ポインタを初期化し、「親」メソッドを呼び出すための戦略を選択するためのグルーコードです。ほとんどの場合、を入力するClass klass * = new class()
方がより明確/安全ですstruct class *klass = malloc(sizeof(struct class));klass->fn1 = ...;klass->fnN = ...
。