それとも逆になりましたか?
私が聞いたところによると、C#がC ++よりも高速であることが証明されているいくつかの領域がありますが、私はそれを自分でテストする勇気がありませんでした。
これらの違いを詳細に説明したり、この情報の適切な場所を私に示したりできると思いました。
それとも逆になりましたか?
私が聞いたところによると、C#がC ++よりも高速であることが証明されているいくつかの領域がありますが、私はそれを自分でテストする勇気がありませんでした。
これらの違いを詳細に説明したり、この情報の適切な場所を私に示したりできると思いました。
回答:
JITを備えたC#やJavaなどのバイトコードベースの言語がC ++コードほど高速にできないという厳密な理由はありません。ただし、C ++コードは長い間非常に高速でしたが、現在でも多くの場合、そうです。これは主に、より高度なJIT最適化の実装が複雑であり、本当にクールなJIT最適化がたった今到着しているためです。
したがって、多くの場合、C ++の方が高速です。しかし、これは答えの一部にすぎません。C ++が実際に高速であるケースは、高度に最適化されたプログラムであり、エキスパートプログラマーがコード全体を徹底的に最適化しています。これは非常に時間がかかる(そして高価になる)だけでなく、一般的には最適化しすぎてエラーが発生します。
一方、インタプリタ言語のコードは、何もしなくても、ランタイムの新しいバージョン(.NET CLRまたはJava VM)で高速になります。そして、JITコンパイラーが実行できる多くの便利な最適化がありますが、ポインターを使用する言語ではこれは不可能です。また、ガベージコレクションは通常、手動のメモリ管理と同じかそれ以上に高速である必要があると主張する人もいます。多くの場合はそうです。通常、これらのすべてをC ++またはCで実装して実現できますが、はるかに複雑でエラーが発生しやすくなります。
ドナルドクヌースが言ったように、「時期尚早な最適化はすべての悪の根源です」。アプリケーションがほとんどの場合、パフォーマンスが非常に重要な算術演算で構成されること、そしてそれがボトルネックになること、C ++で確実に高速になること、そしてC ++が他のアプリケーションと競合しないことを確信している場合要件は、C ++のために行きます。それ以外の場合は、最初にアプリケーションを適切な言語で正しく実装することに集中し、実行速度が遅すぎる場合はパフォーマンスのボトルネックを見つけ、コードを最適化する方法を検討します。最悪の場合、外部関数インターフェイスを介してCコードを呼び出す必要があるかもしれません。そのため、下位レベルの言語で重要な部分を書くことができます。
正しいプログラムを最適化するのは比較的簡単ですが、最適化されたプログラムを修正するのははるかに難しいことに注意してください。
速度の利点の実際のパーセンテージを与えることは不可能であり、それはコードに大きく依存します。多くの場合、プログラミング言語の実装はボトルネックすらありません。http://benchmarksgame.alioth.debian.org/にあるベンチマークを大いに懐疑的に受けてください。これらは主に算術コードをテストしているため、コードにまったく似ていない可能性が高いからです。
C#は高速ではないかもしれませんが、YOU / MEは高速になります。それが私がすることの最も重要な尺度です。:)
オレンジが5つ早くなります。むしろ:(正しい)包括的な回答はありません。C ++は静的にコンパイルされた言語です(ただし、プロファイルに基づく最適化も行われます)。C#は、JITコンパイラーによって支援されて実行されます。違いが非常に多いため、「どれだけ速く」などの質問に答えることはできません。
私はこの質問に対する受け入れられた(そして十分に賛成された)回答の一部に同意することから始めます:
実際には、JITされたコードが適切に最適化されたC ++(またはランタイムオーバーヘッドのない他の言語)プログラムよりも実行速度が遅くなる多くの理由があります。
実行時にコードのJITtingに費やされる計算サイクルは、プログラムの実行では使用できません。
JITterのホットパスは、CPUの命令とデータキャッシュのコードと競合します。パフォーマンスに関しては、キャッシュが支配的であり、C ++のようなネイティブ言語は、定義上、このタイプの競合がないことを知っています。
ランタイムオプティマイザのタイムバジェットは、コンパイル時オプティマイザのタイムバジェットよりも必然的にはるかに制約されます(別のコメンターが指摘したように)。
ボトムラインは:最終的に、あなたがしますほぼ確実にあなたがC#でできるよりもC ++で速い実装を作成することができます。
さて、そうは言っても、タスク、問題ドメイン、ハードウェア、実装の品質、およびその他の多くの要因などの変数が多すぎるため、実際にはどれほど高速なのかを定量化することはできません。シナリオでテストを実行してパフォーマンスの違いを判断し、追加の作業と複雑さの価値があるかどうかを判断します。
これは非常に長くて複雑なトピックですが、C#のランタイムオプティマイザーは優れており、コンパイル時にC ++では利用できない特定の動的最適化を実行時に実行できることは、完全性のために言及する価値があると思います( static)オプティマイザ。これを使用しても、通常、利点はネイティブアプリケーションの法廷に深くありますが、動的オプティマイザーが上記の「ほぼ確実に」修飾子の理由です。
-
相対的なパフォーマンスに関しては、他のいくつかの回答で見た数字や議論にも不安を感じていたので、チャイムをすると同時に、上記で述べた声明をある程度サポートすると思いました。
これらのベンチマークの問題の大きな部分は、C#を記述しているかのようにC ++コードを記述できず、代表的な結果が得られることです(たとえば、C ++で数千のメモリ割り当てを実行すると、恐ろしい数が得られます)。
代わりに、もう少し慣用的なC ++コードを記述して、提供されているC#コード@Wioryと比較しました。C ++コードに加えた2つの主な変更は次のとおりです。
1)使用されるvector :: reserve()
2)キャッシュの局所性を改善するために2D配列を1Dにフラット化(連続ブロック)
C#(。NET 4.6.1)
private static void TestArray()
{
const int rows = 5000;
const int columns = 9000;
DateTime t1 = System.DateTime.Now;
double[][] arr = new double[rows][];
for (int i = 0; i < rows; i++)
arr[i] = new double[columns];
DateTime t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
t1 = System.DateTime.Now;
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
arr[i][j] = i;
t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
}
実行時間(リリース):Init:124ms、Fill:165ms
C ++ 14(Clang v3.8 / C2)
#include <iostream>
#include <vector>
auto TestSuite::ColMajorArray()
{
constexpr size_t ROWS = 5000;
constexpr size_t COLS = 9000;
auto initStart = std::chrono::steady_clock::now();
auto arr = std::vector<double>();
arr.reserve(ROWS * COLS);
auto initFinish = std::chrono::steady_clock::now();
auto initTime = std::chrono::duration_cast<std::chrono::microseconds>(initFinish - initStart);
auto fillStart = std::chrono::steady_clock::now();
for(auto i = 0, r = 0; r < ROWS; ++r)
{
for (auto c = 0; c < COLS; ++c)
{
arr[i++] = static_cast<double>(r * c);
}
}
auto fillFinish = std::chrono::steady_clock::now();
auto fillTime = std::chrono::duration_cast<std::chrono::milliseconds>(fillFinish - fillStart);
return std::make_pair(initTime, fillTime);
}
実行時間(リリース):Init:398µs(はい、それはマイクロ秒です)、Fill:152ms
観察
C#実装を同じ1D配列実装に変更すると、Init:40ms、Fill:171ms、Total:211ms(C ++は依然としてほぼ40%高速でした)。
どちらの言語でも「通常の」コードを書くよりも、C ++で「高速」なコードを設計して書く方がはるかに困難です。
C ++でパフォーマンスが低下するのは(おそらく)驚くほど簡単です。予約されていないベクターのパフォーマンスでそれがわかりました。そして、このような落とし穴がたくさんあります。
実行時に行われているすべてのことを考えると、C#のパフォーマンスは驚くべきものです。そして、そのパフォーマンスは比較的簡単にアクセスできます。
C ++とC#のパフォーマンスを比較するその他の事例データ:https : //benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore
つまり、C ++を使用すると、パフォーマンスをより詳細に制御できます。ポインタを使用しますか?参照?スタックメモリ?ヒープ?動的ポリモーフィズムまたは静的ポリモーフィズム(テンプレート/ CRTPを介して)を使用してvtableのランタイムオーバーヘッドを排除?あなたが...えー持つC ++では、してもらう理想的なので、あなたのソリューション最高のアドレスの問題、あなたにしているタックルこと、(およびそれ以上)を自分でこれらすべての選択を行います。
上記の簡単な例でも、パフォーマンスは大幅に改善されていますが、アクセスするにはより多くの投資が必要であることがわかります。
int[,]
...例に従ってください。
私の経験では(そして私は両方の言語で多くの作業をしてきました)、C ++と比較したC#の主な問題はメモリ消費量が高く、それを制御する良い方法を見つけていません。最終的に.NETソフトウェアの速度を低下させるのは、メモリ消費でした。
もう1つの要因は、JITコンパイラは実行時に実行されるため、高度な最適化を実行するのに時間をかけすぎることができず、時間がかかりすぎるとエンドユーザーがそれに気付くからです。一方、C ++コンパイラには、コンパイル時に最適化を行う必要があるすべての時間があります。この要素は、メモリ消費量よりもそれほど重要ではありません。
C ++がまだ優位に立っている1つの特定のシナリオは、多態性の決定がコンパイル時に事前に決定できるときに発生します。
一般に、カプセル化と据え置きの意思決定は、コードをより動的にし、変化する要件への適応を容易にし、フレームワークとして使いやすくするため、良いことです。これが、C#のオブジェクト指向プログラミングが非常に生産的であり、「一般化」という用語で一般化できる理由です。残念ながら、この特定の種類の一般化は、実行時にコストがかかります。
通常、このコストは実質的ではありませんが、仮想メソッド呼び出しとオブジェクト作成のオーバーヘッドが違いをもたらす可能性があるアプリケーションがあります(特に、仮想メソッドはメソッド呼び出しのインライン化などの他の最適化を妨げるため)。これは、C ++に大きな利点があるところです。テンプレートを使用して、実行時に影響を与えるが、必ずしもすべての少ない多型OOP以上ではありませんが。実際、OOPを構成するすべてのメカニズムは、テンプレート技術とコンパイル時の解決のみを使用してモデル化できます。
そのような場合(そして確かに、それらはしばしば特別な問題ドメインに制限されています)、C ++はC#および同等の言語に勝っています。
sort(arr, generic_comparer)
C ++(またはそのことについてはC)では、データ構造をきめ細かく制御できます。ビットいじりたい場合は、そのオプションがあります。Java / .NETライブラリの内部データ構造を使用する大規模なマネージJavaまたは.NETアプリ(OWB、Visual Studio 2005)は、それらの手荷物を運びます。400 MBを超えるRAMとBIDSをキューブまたはETLの設計に使用するOWBデザイナーセッションも100 MBに入るのを見てきました。
予測可能なワークロード(プロセスを何度も繰り返すほとんどのベンチマークなど)では、JITは、実用的な違いがないように十分に最適化されたコードを取得できます。
大規模なアプリケーションでのIMOの違いは、コード自体が使用しているデータ構造ほどJITではありません。アプリケーションがメモリを多く使用する場合、キャッシュの使用効率が低下します。最近のCPUでのキャッシュミスは非常に高価です。CまたはC ++が実際に成功するのは、データ構造の使用を最適化してCPUキャッシュを適切に再生できる場所です。
グラフィックスの場合、標準のC#グラフィックスクラスは、C / C ++を介してアクセスされるGDIよりもはるかに低速です。これは言語自体とは関係ありませんが、.NETプラットフォーム全体とは関係ありませんが、グラフィックスはGDIの代替として開発者に提供されるものであり、パフォーマンスが非常に悪いので、グラフィックスを作成することすらしませんそれと。
グラフィックライブラリの速度を確認するために使用する簡単なベンチマークがあります。これは、ウィンドウにランダムな線を描画するだけです。C ++ / GDIは、10000行といまだに素晴らしく、C#/ Graphicsは、リアルタイムで1000行を実行することが困難です。
ガベージコレクションは、Java#をリアルタイムシステムに使用できない主な理由です。
GCはいつ発生しますか?
どのくらい時間がかかりますか?
これは非決定的です。
C#がC ++に匹敵するかどうかを判断する必要があり、そのためのテストプログラムをいくつか作成しました(両方の言語でVisual Studio 2005を使用)。ガベージコレクションがなく、言語(フレームワークではない)のみを考慮すると、C#は基本的にC ++と同じパフォーマンスを発揮することがわかりました。C ++の場合よりもC#の場合の方がメモリ割り当てが高速であり、キャッシュサイズの境界を超えてデータサイズが大きくなると、C#の確定性はわずかに低下します。ただし、これらすべては最終的には有料となり、ガベージコレクションが原因で、C#の非決定的なパフォーマンスヒットという形で莫大なコストがかかります。
C / C ++は、大規模な配列、または(任意のサイズの)配列に対する重いループ/反復のいずれかがあるプログラムで非常に優れたパフォーマンスを発揮します。これは、C / C ++では一般にグラフィックスがはるかに高速である理由です。これは、重い配列操作がほとんどすべてのグラフィックス操作の根底にあるためです。.NETは、すべての安全性チェックのために、配列のインデックス作成操作が遅いことで有名であり、これは特に多次元配列に当てはまります(そうです、長方形のC#配列はギザギザのC#配列よりもさらに遅いです)。
C / C ++のボーナスは、直接ポインタを使い続け、Boost std::vector
やその他の高レベルのコンテナ、およびinline
可能なすべての小さな関数を避けた場合に最も顕著になります。可能な限り、昔ながらのアレイを使用してください。はい。高レベルのコンテナーを回避するため、JavaまたはC#で行ったのと同じことを行うには、より多くのコード行が必要になります。動的なサイズの配列が必要な場合new T[]
は、対応するdelete[]
ステートメントとペアにすることを覚えておく必要があります(またはstd::unique_ptr
)—速度を上げると、より慎重にコーディングする必要があります。しかし、それと引き換えに、マネージメモリ/ガベージコレクタのオーバーヘッドを取り除くことができます。オーバーヘッドは、Javaと.NETの両方で重いオブジェクト指向のプログラムの実行時間の20%以上になり、大規模なマネージドメモリアレイのインデックス作成コスト。C ++アプリは、特定の特定のケースで、いくつかの気の利いたコンパイラスイッチからも恩恵を受けることができます。
私はC、C ++、Java、C#のエキスパートプログラマです。最近、まったく同じアルゴリズムプログラムを後者の3言語で実装するまれな機会がありました。プログラムには、多くの数学および多次元配列演算がありました。これを3つの言語すべてで大幅に最適化しました。結果は、それほど厳密ではない比較で通常見られるものの典型的なものでした。JavaはC#よりも約1.3倍高速でした(ほとんどのJVMはCLRよりも最適化されています)。C#プログラムは安全なコードのみを使用したことに注意してくださいunsafe
。キーワードを使用する前に、C ++でコード化することもできます。
誰かが私がC#に対して何かを持っていると思わないように、C#はおそらく私のお気に入りの言語だと言って締めくくります。これは、これまでに出会った中で最も論理的で直感的で迅速な開発言語です。プロトタイピングはすべてC#で行います。C#言語には、Javaに比べて多くの小さな微妙な利点があります(そうです、マイクロソフトがゲームに遅れをとり、間違いなくJavaをコピーすることで、Javaの欠点の多くを修正する機会があったことを知っています)。Calendar
誰でもJavaのクラスに乾杯?マイクロソフトがCLRと.NET JITterを最適化するために真の努力を費やした場合、C#が真剣に引き継ぐ可能性があります。正直なところ、彼らがまだそうしていないことに驚いています。C#言語で非常に多くのことを正しく行っているので、コンパイラーの強力な最適化をフォローしてみませんか?たぶん、みんなが物乞いしたら。
new T[]
対応するものとペアリングすることを覚えておく必要がdelete[]
あります」 –いいえ、必要ありません。あなたのstd::unique_ptr
ためにそれをする必要があります。
>聞いたことから...
あなたが聞いたことを信頼できるかどうかを判断するのはあなたの難しさのようで、このサイトでの返信を評価しようとすると、その難しさが繰り返されます。
人々がここで言うことは、あなたが最初に聞いたものよりも多かれ少なかれ信頼できるものであるかどうかをどのように決定しますか?
1つの方法は、証拠を求めることです。
誰かが「C#がC ++よりも高速であることが証明されている領域がある」と主張するとき、彼らになぜそう言うのかを尋ね、測定値を見せてもらい、プログラムを見せてもらいます。時々彼らは単に間違いをしたでしょう。時には、彼らが真実であることを示すことができる何かを共有するのではなく、単に意見を表明していることに気付くでしょう。
多くの場合、情報と意見は人々が主張するもので混同され、どちらがどれであるかを整理する必要があります。たとえば、このフォーラムの返信から:
「 これらは主に算術コードをテストしているため、http: //shootout.alioth.debian.org/のベンチマークを大いに懐疑的に考えてください。これはおそらくコードとまったく似ていない可能性があります。」
「これらの大部分はテスト算術コード」の意味を本当に理解しているかどうかを自問し、次に作者が彼の主張が真実であることを実際に示しているかどうか自問してください。
「これは実際には個々のプログラムがどれだけ最適化されているかに依存するため、あまり役に立たないテストです。いくつかのプログラムを4〜6倍以上高速化でき、最適化されていないプログラム間の比較はかなり明確になっています。ばかげた」
著者が実際に「それらのいくつかを4〜6倍以上高速化した」ことを実際に示したかどうかを自問してください。これは簡単に主張できます。
「恥ずかしいほど並列」の問題の場合、C ++でIntel TBBとOpenMPを使用すると、C#とTPLで行われた同様の(純粋な計算)問題と比較して、パフォーマンスが約10倍向上しました。SIMDはC#が競合できない領域の1つですが、TPLにはかなりのオーバーヘッドがあるという印象も受けました。
そうは言っても、マルチスレッド化して結果をすばやく得ることができることがわかっているパフォーマンス重視のタスクにのみC ++を使用しています。それ以外の場合は、C#(場合によってはF#)で十分です。
それは本当に明確な答えがない非常に曖昧な質問です。
例えば; パフォーマンスは確かにはるかに優れているので、C#ではなくC ++で作成された3Dゲームをプレイしたい。(そして私はXNAなどを知っていますが、それは本当のところにはほど遠いものです)。
一方、前述のとおり、必要なことをすばやく実行できる言語で開発し、必要に応じて最適化する必要があります。
.NET言語はC ++コードと同じくらい高速になる場合がありますが、C ++コードは、.NETランタイムがGCのために一時停止する必要があるため、一時停止について非常に賢い場合でも、より一定したスループットを実現します。
したがって、一時停止なしで一貫して高速に実行する必要があるコードがある場合、ランタイムGCに非常に注意していても、.NETはある時点でレイテンシを導入します。
理論的には、サーバータイプのアプリケーションを長時間実行する場合、JITでコンパイルされた言語は、ネイティブにコンパイルされた言語よりもはるかに高速になる可能性があります。JITコンパイル済み言語は通常、最初にかなり低レベルの中間言語にコンパイルされるため、とにかくコンパイル時に多くの高レベルの最適化を実行できます。JITがアプリケーションの使用状況に関するデータを取得するにつれて、JITがコードのセクションをその場で再コンパイルし続けることができるという大きな利点があります。最も一般的なコードパスを配置して、分岐予測が可能な限り頻繁に成功できるようにします。しばしば一緒に呼び出される個別のコードブロックを再配置して、両方をキャッシュに保持することができます。内部ループの最適化により多くの労力を費やすことができます。
これが.NETまたはJREのいずれかによって行われることは疑わしいですが、私が大学にいたときに調査されていたので、これらの種類のものがすぐに現実世界に入る可能性があると考えることは不合理ではありません。
私はvector
C ++とC#の同等のものList
、および単純な2D配列でテストしました。
Visual C#/ C ++ 2010 Expressエディションを使用しています。どちらのプロジェクトもシンプルなコンソールアプリケーションです。標準(カスタム設定なし)リリースとデバッグモードでテストしました。私のPCではC#リストの実行が速く、C#では配列の初期化も速く、数学演算が遅くなります。
Intel Core2Duo P8600 @ 2.4GHz、C#-.NET 4.0を使用しています。
ベクターの実装がC#リストとは異なることは知っていますが、オブジェクトの格納に使用するコレクションをテストしたいと思っています(インデックスアクセサーを使用できます)。
もちろん、メモリをクリアする必要があります(を使用するたびに言いましょうnew
)が、私はコードを単純にしたかったのです。
C ++ベクトルテスト:
static void TestVector()
{
clock_t start,finish;
start=clock();
vector<vector<double>> myList=vector<vector<double>>();
int i=0;
for( i=0; i<500; i++)
{
myList.push_back(vector<double>());
for(int j=0;j<50000;j++)
myList[i].push_back(j+i);
}
finish=clock();
cout<<(finish-start)<<endl;
cout<<(double(finish - start)/CLOCKS_PER_SEC);
}
C#リストテスト:
private static void TestVector()
{
DateTime t1 = System.DateTime.Now;
List<List<double>> myList = new List<List<double>>();
int i = 0;
for (i = 0; i < 500; i++)
{
myList.Add(new List<double>());
for (int j = 0; j < 50000; j++)
myList[i].Add(j *i);
}
DateTime t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
}
C ++-配列:
static void TestArray()
{
cout << "Normal array test:" << endl;
const int rows = 5000;
const int columns = 9000;
clock_t start, finish;
start = clock();
double** arr = new double*[rows];
for (int i = 0; i < rows; i++)
arr[i] = new double[columns];
finish = clock();
cout << (finish - start) << endl;
start = clock();
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
arr[i][j] = i * j;
finish = clock();
cout << (finish - start) << endl;
}
C#-配列:
private static void TestArray()
{
const int rows = 5000;
const int columns = 9000;
DateTime t1 = System.DateTime.Now;
double[][] arr = new double[rows][];
for (int i = 0; i < rows; i++)
arr[i] = new double[columns];
DateTime t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
t1 = System.DateTime.Now;
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
arr[i][j] = i * j;
t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
}
時間:(リリース/デバッグ)
C ++
(はい、13秒です。デバッグモードのリスト/ベクターには常に問題があります。)
C#:
まあ、それは異なります。バイトコードはマシンコードに変換されている場合は(だけではなくJIT)(I平均あなたがプログラムを実行している場合)と、プログラムが多くの割り当て/割り当て解除を使用している場合、それは速いので、可能性がGCのアルゴリズムは一つだけのパスを必要とする(理論上)メモリ全体を1回通過しますが、通常のmalloc / realloc / free C / C ++呼び出しは、すべての呼び出しでオーバーヘッドを引き起こします(呼び出しオーバーヘッド、データ構造オーバーヘッド、キャッシュミス;))。
したがって、理論的には可能です(他のGC言語についても)。
ほとんどのプログラマーはとにかくそれを使用しないので、ほとんどのアプリケーションでC#でメタプログラミングを使用できないという極端な欠点は本当にわかりません。
もう1つの大きな利点は、SQLがLINQの「拡張」のように、データベースへの呼び出しを最適化する機会をコンパイラーに提供することです(つまり、コンパイラーは、呼び出された関数がインライン化されている1つの「blob」バイナリーにLINQ全体をコンパイルできます。あなたの使用のために最適化されていますが、私はここで推測しています)。
C#で書かれたアプリケーションが高速で実行されているだけでなく、C ++で作成されたアプリが高速で実行されていると思います(C ++はちょうど古い...そしてUNIXも...)
-問題は、実際には-それは何ですか、ユーザー開発者は不満を言っています...
C#でコードを非常にシンプルで高速に書くこと(エラーの可能性も増えることを忘れないでください。C++の場合、開発者はメモリリークについて不平を言います)-クラッシュ、DLL間の呼び出し、および「DLL hell」の問題-新しいライブラリによるサポートライブラリと置換ライブラリの問題...
プログラミング言語のスキルが高ければ高いほど、ソフトウェアの品質(および速度)が高くなります。
まあ、私見、C#の場合、私たちは非常に快適なUI、ライブラリーの非常に素晴らしい階層、そしてCLIのインターフェースシステム全体を持っています。C ++の場合、テンプレート、ATL、COM、MFC、およびOpenGL、DirectXなどの既に記述された実行中のコード全体のシバンがあります...開発者は、C#の場合、GC呼び出しが確実に発生しないと不平を言っています(プログラムが高速に実行され、 1秒で-強打!
私はこのように言います:より高速なコードを書くプログラマーは、現在のマシンを高速化するものについてより多くの情報を提供されるプログラマーであり、偶然にも、彼らはまた、正確な低レベルかつ確定性を可能にする適切なツールを使用するものです最適化手法。これらの理由から、これらの人々はC#ではなくC / C ++を使用する人々です。私はこれを事実として述べるまで行きます。
私が間違っていなければ、C#テンプレートは実行時に決定されます。これは、C ++のコンパイル時テンプレートよりも低速でなければなりません。
そして、他の多くの人が言及している他のすべてのコンパイル時最適化を取り入れると、安全性の欠如だけでなく、実際にはより高速になります...
生の速度と最小のメモリ消費量の点で、C ++が明らかな選択だと思います。しかし、これはコードの開発により多くの時間を費やし、メモリのリークやNULLポインタ例外の発生がないことを意味します。
評決:
C#:開発が速く、実行が遅い
C ++:遅い開発、速い実行。
これは、実際にコードで達成しようとしていることに依存します。VB.NET、C#、マネージドC ++の間にパフォーマンスの違いがあるというのは都市の伝説にすぎないと聞いています。ただし、少なくとも文字列の比較では、マネージドC ++がC#からズボンを打ち負かし、それがVB.NETからズボンを打ち負かすことがわかりました。
言語間のアルゴリズムの複雑さを徹底的に比較したことはありません。また、各言語のデフォルト設定も使用しています。VB.NETでは、変数の宣言などを要求するために設定を使用しています。マネージドC ++に使用しているコードは次のとおりです(ご覧のとおり、このコードは非常に簡単です)。.NET 4.6.2を使用するVisual Studio 2013の他の言語でも同じように実行しています。
#include "stdafx.h"
using namespace System;
using namespace System::Diagnostics;
bool EqualMe(String^ first, String^ second)
{
return first->Equals(second);
}
int main(array<String ^> ^args)
{
Stopwatch^ sw = gcnew Stopwatch();
sw->Start();
for (int i = 0; i < 100000; i++)
{
EqualMe(L"one", L"two");
}
sw->Stop();
Console::WriteLine(sw->ElapsedTicks);
return 0;
}
C#とC ++の間には、パフォーマンスの面でいくつかの大きな違いがあります。
そのほかに、プログラマーの能力も役割を果たします。クラス全体で引数として値によって渡されるクラスが不適切なC ++コードを見たことがあります。実際に何をしているのかわからない場合、C ++では実際にパフォーマンスが低下する可能性があります。
>結局のところ、答えはどこかにあるはずですよね。:)
うーん、違う。
いくつかの回答が指摘しているように、質問は回答ではなく質問に応じて招待する方法で詳細に指定されていません。たった1つの方法で:
そして、どのプログラム?どの機械?どのOSですか?どのデータセット?
これに触発されて、私はほとんどのプログラムで必要な一般的な命令の60%で簡単なテストを行いました。
C#コードは次のとおりです。
for (int i=0; i<1000; i++)
{
StreamReader str = new StreamReader("file.csv");
StreamWriter stw = new StreamWriter("examp.csv");
string strL = "";
while((strL = str.ReadLine()) != null)
{
ArrayList al = new ArrayList();
string[] strline = strL.Split(',');
al.AddRange(strline);
foreach(string str1 in strline)
{
stw.Write(str1 + ",");
}
stw.Write("\n");
}
str.Close();
stw.Close();
}
文字列配列とarraylistは、これらの命令を含めるために意図的に使用されています。
これがc ++コードです:
for (int i = 0; i<1000; i++)
{
std::fstream file("file.csv", ios::in);
if (!file.is_open())
{
std::cout << "File not found!\n";
return 1;
}
ofstream myfile;
myfile.open ("example.txt");
std::string csvLine;
while (std::getline(file, csvLine))
{
std::istringstream csvStream(csvLine);
std::vector csvColumn;
std::string csvElement;
while( std::getline(csvStream, csvElement, ‘,’) )
{
csvColumn.push_back(csvElement);
}
for (std::vector::iterator j = csvColumn.begin(); j != csvColumn.end(); ++j)
{
myfile << *j << ", ";
}
csvColumn.clear();
csvElement.clear();
csvLine.clear();
myfile << "\n";
}
myfile.close();
file.close();
}
私が使用した入力ファイルのサイズは40 KBでした。
そして、これが結果です-
ああ、でもこれはLinuxで... C#がMonoで実行されていて...そしてC ++がg ++で。
OK、これは私がWindowsで得たものです– Visual Studio 2003: