34

私は OK の C/C++ プログラマーです。Haskell は非常に興味深いと思います。しかし、Haskell のきれいなコードを書くのは比較的簡単ですが、それは数学 (私はとても快適です) をかなりよく模倣しているので、Haskell で高速に実行されるきれいなコードを書くのは非常に難しいように思えます。

Haskell のクイックソートのより高速なバージョンは、非常に長く恐ろしいものです。これは、素朴で短い (2 行) クリーンで直感的な実装とは似ていません。Haskell の長くて恐ろしいバージョンは、実際には、短くて単純な C のカウンター部分よりもはるかに遅いです。

それは、現在の Haskell コンパイラがあまりにも馬鹿げているからでしょうか、それとも人間 (もちろん SJP 以外) が高速な Haskell コードを書くのは不可能なのでしょうか?

4

5 に答える 5

61

学習とパフォーマンスという 2 つの異なる質問をします。

  • map再帰、パターン マッチング、 、filter、を使用した関数型プログラミングに慣れるまでに約 1 か月かかりましたfold。私はすべて ML で行いましたが、非常に簡単に Haskell に変換されました。
  • モナドについて理解するのに 2、3 年かかりましたが、それは間違ったものを読んだからです。今はもっと良いチュートリアルがあると思います。しかし、あなたが始めているのであれば、モナドをしばらく避けてください。
  • 新しい型クラスを作成できるようになるまで数か月かかりました、既存の型クラスを使用するのは簡単でした。
  • 遅延評価のこつを持っているかどうかはまだわかりません。しかし、私は Haskell の純粋さが好きで、遅延評価を不幸なアクシデントとして扱う傾向があり、(John Hughes のように) 少数の人々だけが悪用する方法を知っています。

Tony Hoare が命令型言語用に設計し、Haskell に変換しようとした、ミューテーションを搭載したアルゴリズムを適応させたために、パフォーマンスの問題が発生しただけです。Haskell では、他の関数型言語と同様に、高価な操作は割り当てです。マージソートを書いてみると、それがシンプルで非常にうまく機能することがわかるでしょう。

将来同様の過ちを犯さないようにするにはどうすればよいですか。Chris Okasaki の著書Purely Functional Data Structuresをご覧ください。優れた本であり、パフォーマンスをあきらめることなく「物事を行う機能的な方法」を学ぶのに役立ちます.

于 2008-12-20T04:19:54.947 に答える
22

Haskell でクイックソートがそれほど速くないのには、非常に具体的な理由があります。これは、その仕組みに華麗なハッカーが織り込まれたアルゴリズムの神のような例です。この場合のハッカーとは、真の Haskell 信奉者が不必要に危険で非数学的であると見なす技術のことです。元の実装では、Haskell が自らに課したルールを破るためにあらゆる努力が払われました。本物のクイックソートは、ストレージ スロットを新しい情報で上書きすることによって機能します。Haskell では、既存の情報のまったく新しいコピーを作成する方がはるかに簡単です。

したがって、単純な 2 行の Haskell バージョンは、クイックソートの本質の一部を捉えていますが (同じ数のキー比較を行います)、実際にはクイックソートではありません。既存の値の状態を微調整する能力を最大限に活用した天才の多くの部分が欠けています。そのため、リストの断片の中間コピーを大量に作成します。

憶測: Haskell コンパイラは、Hoare (クイックソートの発明者) と同じ推論を適用してコードを分析し、ステートフルな方法で完全に再実装することでコードを最適化できると判断できるでしょうか? おそらく。

于 2008-12-18T07:33:20.113 に答える
13

重要なのは、速い Haskell コードを書くことではなく、Haskell コードを速く書くことです。そこに到達し、コードを高速化する必要がある場合は、最適化を開始します (または FFI を使用します。C++ のスキルを忘れる必要はありません)。Haskell では、最初にエレガンス、信頼性、保守性を求めます。Haskell-fu にプロファイリングを追加して、使用されていない最適化に時間を無駄にしないようにします。また、時期尚早に最適化しないことを忘れないでください。

于 2008-12-18T08:58:48.587 に答える
8

したがって、タイトルの質問に答えると、Haskell の基本を短時間で理解できるようになるでしょう。特に関数型プログラミングに慣れている場合はなおさらです。遅延性、型クラス、型ファミリー、そしてもちろん恐ろしいモナド (および矢印) など、Haskell を本当に際立たせるものを理解して慣れるには、さらに時間がかかる可能性があります。言語を学習するための優れたリソースがあり、その多くは無料で利用でき、役立つコミュニティもあります。したがって、1、2 週間程度の真剣な学習で快適に過ごせるようになると思います ;-)

Lisp を実際に何にも使わなくても学ぶ価値があると主張する人がいるのと同じように、それだけの価値はあると思います。より優れたプログラマーになるため、価値があります。つまり、考え方が変わります。Haskell にも同様の効果があると思います。

于 2008-12-19T22:33:54.830 に答える
4

その理由は、コンピューターの数学的基礎は、一般的な Haskell や関数型言語の数学的基礎とは異なるためです。

コンパイラが直面している問題の味を知るために... Haskell プログラムを C に変換し、可能な限りオリジナルに近づけてから、その C コードを最適化してみてください (C の方法でゼロから書き直すことはありません)。

愚かではありませんが、関数型言語はパフォーマンスのために作られているわけではなく、簡潔な数学的に単純な表記法は無料では提供されません。

于 2008-12-18T08:29:55.977 に答える