35

分散/並行/フェイルオーバー/スケーラブルなバックエンド環境でJavaの代替案を検討しているときに、Erlangを発見しました。私は本や記事に時間を費やしましたが、ほとんどすべての人(Java中毒の人でさえ)は、エラーが発生しにくい方法で多くの便利なものが箱から出されているので、Erlangがそのような環境でより良い選択であると言います。

ほとんどの場合、Erlangは、異なるガベージコレクション戦略(プロセスごと)、共有状態(b / wスレッドとプロセス)の欠如、およびよりコンパクトなデータ型のために、より高速であると確信していました。しかし、ErlangとJavaの数学サンプルの比較を見つけたとき、私は非常に驚きました。Erlangは、たとえばx10からx100まで、数桁遅くなっています。

並行タスクでも、複数のコアと1つのコアの両方で。

その理由は何ですか?これらの答えが思い浮かびました:

  • ほとんどのタスクでのJavaプリミティブ(=>ヒープ/ gcなし)の使用
  • JavaコードとErlangプロセスのスレッド数が同じであるため、アクターモデルにはここでは利点がありません
  • または、Javaは静的に型付けされていますが、Erlangは型付けされていません
  • 他に何かありますか?

これらが非常に特殊な数学アルゴリズムであるためである場合、誰かがより現実的な/実践的なパフォーマンステストを示すことができますか?

更新:これまでのところ、Erlangはそのような特定の「高速Javaケース」に適したツールではないことを要約した答えがありますが、私にはわかりません-ここでのこのようなErlangの非効率性の主な理由は何ですか:動的型付け、GCまたは貧弱なネイティブコンパイル?

4

7 に答える 7

33

Erlangは数学のために作られたものではありません。通信、並列処理、スケーラビリティを念頭に置いて構築されているため、数学のタスクをテストすることは、削岩機がさわやかなマッサージ体験を提供するかどうかをテストすることに少し似ています。

そうは言っても、少し話を変えましょう。JVMで
Erlangスタイルのプログラミングが必要な場合は、Scala ActorsAkkaフレームワーク、またはVert.xを見てください。

于 2012-11-29T15:53:37.867 に答える
14

ベンチマークは、実際にテストしていること以外のことを言うのに決して適していません。ベンチマークがプリミティブと古典的なスレッドモデルのみをテストしていると感じる場合は、それについて知識を得ることができます。これで、Javaは、プリミティブの数学や、これらのタイプの問題の従来のスレッドモデルでErlangよりも高速であると自信を持って言うことができます。ベンチマークではテストされていないため、スレッド数が多い場合のパフォーマンスや、より複雑な問題については何もわかりません。

ベンチマークでテストされた種類の数学を実行している場合は、Javaを使用してください。これは、明らかにその仕事に適したツールだからです。共有状態がほとんどまたはまったくない、非常にスケーラブルなことをしたい場合は、そのベンチマークを見つけるか、少なくともErlangを再評価してください。

Erlangで本当に重い計算をする必要がある場合は、HiPEの使用を検討してください(とにかくそれを考慮してください)。

于 2012-11-29T15:43:56.887 に答える
8

他の回答で指摘されているように、Erlangは、ベンチマークの問題とは少し反対の現実の問題を効果的に解決するように設計されています。

しかし、もう1つの側面、つまりerlangコードの忠実さ(場合によっては開発の迅速さを意味する)を啓蒙したいと思います。これは、ベンチマークの実装を比較した後、簡単に結論付けることができます。

たとえば、k-ヌクレオチドベンチマーク:
Erlangバージョン:http://benchmarksgame.alioth.debian.org/u64q/program.php?
test = knucleotide&lang = hipe&id = 3 Javaバージョン: http: //benchmarksgame.alioth.debian.org /u64q/program.php?test=knucleotide&lang=java&id=3

より現実的なベンチマークが必要な場合は、モトローラテレコムソフトウェアのC++とErlangを比較することをお勧めします

于 2012-11-29T16:20:03.027 に答える
7

いくつかのベンチマークは遺伝子シーケンシングなどのerlangに完全に適合しているので、私はこれに興味を持った。したがって、http://benchmarksgame.alioth.debian.org/で最初に行ったのは、CとErlangの両方の逆補完の実装と、テストの詳細を確認することでした。erlangがVM/wスケジューラーを起動するのにかかる時間を割り引いていないため、テストに偏りがあることがわかりました。ネイティブにコンパイルされたCははるかに高速に起動されます。これらのベンチマークの測定方法は基本的に次のとおりです。 time erl -noshell -s revcomp5 main < revcomp-input.txt

ベンチマークによると、Javaは1.4秒、erlang / w HiPEは11秒かかりました。(シングルスレッド)Erlangコードの実行には0.15秒かかりました。仮想マシンの起動にかかる時間を割り引くと、実際のワークロードは3000マイクロ秒しかかかりませんでした( 0.003秒)。

だから私はそれがどのようにベンチマークされているのか分かりません、それが100回行われた場合、erlangVMを起動するコストはx100になるので意味がありません。入力が与えられたよりもはるかに長い場合、それは理にかなっていますが、そのWebページには詳細が表示されません。ベンチマークをマネージド言語に対してより公平にするために、コード(Erlang / Java)にUnixシグナルをPython(ベンチマークを実行している)に送信させ、スタートアップ関数にヒットさせます。

ベンチマークはさておき、erlang VMは基本的に、JavaVMと同様に最後にマシンコードを実行するだけです。したがって、ErlangではJavaよりも数学演算に時間がかかる方法はありません。

Erlangが苦手なのは、頻繁に変更する必要のあるデータです。連鎖ブロック暗号など。文字「0123456789」があるとします。暗号化により、最初の2文字が7で排他的論理和され、最初の2文字が加算された結果で次の2文字が排他的論理和され、次に現在の2文字が減算された結果で前の2文字が排他的論理和されます。次に、次の4文字を排他的論理和します。

Erlangのオブジェクトは不変であるため、これは、変更するたびにchar配列全体をコピーする必要があることを意味します。そのため、erlangは、この正確な問題を解決するために呼び出すことができるCコードであるNIFSと呼ばれるものをサポートしています。実際、Erlangに同梱されているすべての暗号化(ssl、aes、blowfish ..)と圧縮(zlib、..)はCで実装されており、ErlangからCを呼び出すことに関連するコストもほぼ0です。

したがって、Erlangを使用すると、両方の長所を活用でき、Erlangの並列処理でCの速度を得ることができます。

可能な限り最速の方法で逆補完を実装する場合、Cを使用してミューティングコードを記述しますが、Erlangを使用して並列コードを記述します。無限の入力を想定すると、Erlangを分割して> <<Line/binary, ">", Rest/binary>> = read_stream ラウンドロビンを介して最初に利用可能なスケジューラーにブロックをディスパッチします。ラウンドロビンは、ミリ秒ごとにクラスターにリアルタイムで追加される、無限のEC2プライベートネットワーク隠しノードで構成されます。

次に、これらのノードは、処理のためにNIFSを介してCに呼び出し(Cはalioth Webサイトでの逆コンパイルの最速の実装でした)、出力をノードマスターに送り返して、入力者に送信します。

これらすべてをErlangで実装するには、シングルスレッドプログラムを作成しているかのようにコードを作成する必要があり、このコードを作成するのに1日もかかりませんでした。

これをJavaで実装するには、シングルスレッドコードを作成する必要があります。マネージドからアンマネージドへの呼び出しのパフォーマンスヒットを取得し(明らかにうなり声の作業にC実装を使用するため)、サポートするように書き直します。 64コア。次に、複数のCPUをサポートするように書き直します。次に、クラスタリングをサポートするためにもう一度書き直します。次に、メモリの問題を修正するためにもう一度書き直します。

そしてそれは一言で言えばErlangです。

于 2016-02-15T21:57:56.693 に答える
3

ErlangソリューションはETS、Erlang Term Storageを使用します。これは、別のプロセスで実行されるインメモリデータベースのようなものです。別のプロセスにあるため、そのプロセスとの間のすべてのメッセージはシリアル化/逆シリアル化する必要があります。これは多くの遅さの原因になると思います。たとえば、「regex-dna」ベンチマークを見ると、ErlangはJavaよりもわずかに遅いだけで、ETSを使用していません。

于 2015-03-10T20:25:40.377 に答える
2

erlangはすべての値にメモリを割り当てる必要があるのに対し、Javaでは通常、変数を高速にしたい場合は変数を再利用します。つまり、「タイトループ」ベンチマークの場合は常に高速になります。

-clientフラグとボックス化されたプリミティブを使用してJavaバージョンのベンチマークを行い、それをerlangと比較するのは興味深いことです。

活発なプロジェクトではないので、ヒップの使用は不公平だと思います。ミッションクリティカルなソフトウェアがこれで実行されているかどうかを知りたいと思います。

于 2012-12-21T22:41:40.333 に答える
-8

Erlangについては何も知りませんが、これはとにかくリンゴとオレンジのアプローチを比較しているようです。Javaのパフォーマンスを現在の状態にまで改善するために、10年以上にわたってかなりの努力が費やされたことを認識しておく必要があります。

ボランティアや中小企業によって行われた言語の実装がその努力に勝るものがないことは(私にとって)驚くべきことではありません。

于 2012-11-29T16:13:11.183 に答える