2

言語を速度でランク付けすることは困難ですが、実際には、今日、C を使用して最速のプログラムを取得できることは広く受け入れられています。少なくともしばらくの間。ただし、Scheme のスターリン コンパイラについて学んだばかりです。ご存知のように、Scheme は型注釈のない高水準の関数型言語です。それでも、そのコンパイラは、C で直接同等のものよりも1.5​​ 倍から 100 倍高速にプログラムを生成すると主張しています。

その存在を知らなかったという事実は、自分の信念について心配させます。まず、どうしてそれが真実であると言えるのでしょうか? 第二に、これは唯一の例外ではありません。私が気付いていない、C よりも高速なコードを生成する高水準言語または低水準言語の他のコンパイラーはありますか?

4

5 に答える 5

8

あなたはコメントを読むべきです...

素晴らしいですが、C バージョンが遅い理由の 1 つは、fabs の代わりに abs を使用していることです。abs は引数として int を取ります (これはコンパイラの警告です!) – ゼロ以外の double を渡すと、常に大きな数値が返されます。C バージョンは基本的に、エラーが double の解像度を下回るまで繰り返します。

printf(“%d,%d\n”,abs(0.0001)<0.001,fabs(0.0001)<0.001); 出力 0,1

と応答

優秀ポイント!fabs に切り替えると、gcc-inline の速度がスターリンとほぼ同じ速度になります。

そして記事からの引用:

原則として、スターリンは中間の C コードを生成しますが、それはまったく異質で低レベルです。

スターリンはCにコンパイルされるため、Cよりも高速ではありません.スターリンは、あなたよりもタイトで読みにくいCコードを書くのが得意です:-)

ウィキページから:

Stalin (STATic Language ImplementatioN) は、Jeffrey Mark Siskind によって書かれた積極的な最適化バッチ プログラム全体の Scheme コンパイラです。高度なフロー分析と型推論、およびその他のさまざまな最適化手法を使用して、特に数値コードの場合に非常に高速なコード (中間言語として C を使用) を生成します。 [要出典] Stalin は、最適化された実行可能ファイルを生成する際の本番環境での使用を目的としています。

それでは見てみましょう...おそらく使用されている型を推測しようとするコンパイラであり(名前はこれについては非常に明確です)、手書きのCよりも優れています。

一般に、ドメイン固有の問題は、C にはないトリックを使用できるため、C よりも高速になる可能性があります。たとえば、プリミティブ オブジェクトとしてベクトルを持つ言語は、CPU のベクトル命令をより簡単に使用できます。

于 2013-09-13T10:32:34.207 に答える
2

Fortran は、数値計算のアプリケーションで C よりも優れていることがよくあります。多分これは役に立ちます:

Fortran と C++ の比較、Fortran は最近の数値解析でまだ優位性を保っていますか?

于 2013-09-13T15:12:55.197 に答える
2

C - コンパイラの最適化を使用すると、非常に高速なコードが生成されます。非常に時間が重要な割り込み用に、優れた C コンパイラによって作成された最適化後のアセンブラ コードがあります。コンパイラが知らない制約 (たとえば、入力値が常に特定の範囲内にあるなど) を知っている場合でも、コードを 25% 高速化することができます。ただし、Scheme コンパイラも認識しません!!

これは理論的には、C コンパイラによって生成されるコードよりも 1.3 倍高速なコードを記述できることを意味します。しかし、これ以上コードを高速化することはできませんでした。

もう 1 つの非常に高速な言語は Pascal であるため、最新の Pascal バリアント (FreePascal など) は、C コンパイラと同じ実行時間とメモリ消費量を持つ可能性があります。

スキームは宣言型プログラミング言語であり、C は命令型プログラミング言語です。簡単な質問は次のとおりです。「直接同等」とはどういう意味ですか?

次のスキーム コードについて考えてみましょう。

(define (example a) (+ (if (> a 1)  (example (- a 1)) 0) (somefunc a)))

C では、次のように実装できます。

double iffunc(int a,double b,double c)
{
    return a?b:c;
}
double example(int a)
{
    return iffunc(a>1,example(a-1),0)+somefunc(a);
}

ただし、次のように実装することもできます。

double example(int a)
{
    int i;
    double b;
    for(i=1;i<=a;i++) b+=somefunc(i);
    return b;
}

C では、2 番目の実装は、すべてのプログラマーの 99% が使用する実装になります。最初のものよりもはるかに高速です。最初の実装は、Scheme バリアントと「直接同等」です。(Scheme で "for" ループを書くことは不可能です!!)

したがって、最初の実装の速度を Scheme コードの速度と比較すると、実際には 1.5 倍、またはそれ以上の速度になる可能性があります。2 番目の実装の速度を、Scheme コンパイラによって生成されたコードと比較すると、C コンパイラの方が確実に高速になります。

于 2013-09-13T13:27:34.877 に答える
1

それは真実ではない!

C はアセンブリを中間体として使用するため、C は特定のプラットフォームで Assembly よりも高速になることはありません。したがって、C が実装者が手動で行うよりも効率的なコードを作成することは理論的に不可能です。

C にコンパイルされる他のすべての言語では、その言語が同じ作成者によって記述された C コードよりも優れていると期待することはできません。出力が生成された C コードであるため、スターリンはそのような言語です。Stalin の作成者が C で sqrt-iter を実行した場合、Scheme コンパイラによって生成された C コードと同じくらい高速な C になります。スターリンはジャスティン・ドムケが手作業で行うよりも効率的な C コードを作成しますが、それはスターリンが C よりも高速であることを証明するものではありません。スターリンの作者がジャスティン・ドムケよりも C で優れていることを証明するだけです。

現在、C コンパイラは、静的解析、デッド コードの削除、ループ展開、あらゆる種類の最適化手法を使用しています。平均的なプログラマーにとって、C コンパイラーはおそらく、低レベルのコードで生成されるよりも優れたコードを持ち、より短く、より直感的です。上位レベルの言語は、メモリ管理、レジスタ サイズ、ポインター、構文などの不要な要素を抽象化し、コードを小さくしてデバッグを容易にします。これにはコストがかかります。通常は速度ですが、多くの場合、速度と場合によってはメモリ使用量が問題になりますが、効率ほど重要ではありません。おそらく、最適化の 3 つのルールについて聞いたことがありますか?

最終的に、さまざまなプログラミング言語がさまざまなタスクにより適しています。アルゴリズムのブログの選択は、良い例として選択されています。あなたは本当にsqrtそのようなことをしたでしょうか?私はかつて持っていましたが、それは数学演算子としてインクリメント、デクリメント、while-true しか持たない言語でした。

最後に、私はスターリンが好きです。これは、C をよく知っている人からの素晴らしいスキーム コードです。検討する必要がありますが、本当にSchemeを動かしたい場合は、代わりにIkarusを検討してください。

于 2013-09-13T15:39:40.100 に答える