それとも今では逆ですか?
私が聞いたところでは、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コンパイラーによって実行されます。違いが非常に多いため、「どれだけ速く」などの質問に答えることはできません。
私は、この質問に対する受け入れられた(そしてよく支持された)答えの一部に同意しないことから始めます:
実際には、JITtedコードが適切に最適化されたC++(またはランタイムオーバーヘッドのない他の言語)プログラムよりも遅く実行される理由がたくさんあります:
実行時にJITtingコードに費やされる計算サイクルは、プログラムの実行で使用することは定義上不可能です。
jITterのホットパスは、CPUの命令およびデータキャッシュのコードと競合します。パフォーマンスに関してはキャッシュが支配的であり、C++のようなネイティブ言語には定義上このタイプの競合はありません。
ランタイムオプティマイザーのタイムバジェットは、コンパイル時オプティマイザーのタイムバジェットよりもmuchより必然的に制限されます(別のコメンターが指摘したように)
一番下の行:最終的に、あなたはほぼ確実に、C#の場合よりも高速なC++の実装を作成できます。
さて、それで、どれくらい速くが本当に定量化できないのか、あまりにも多くの変数があるので:タスク、問題領域、ハードウェア、実装の品質、および他の多くの要因。シナリオでテストを実行してパフォーマンスの違いを判断し、追加の労力と複雑さに見合う価値があるかどうかを判断します。
これは非常に長くて複雑なトピックですが、完全を期すために、C#のランタイムオプティマイザーは優れており、コンパイル時にC++では利用できない特定の動的最適化を実行時に実行できることに言及する価値があると感じています(静的)オプティマイザー。これでも、通常はネイティブアプリケーションの裁判所に利点がありますが、ダイナミックオプティマイザーが「almost確かに」上記の修飾子。
-
相対的なパフォーマンスに関しては、他の回答で見た数字や議論にも不安を感じていたため、上記の声明を支持すると同時に、チャイムになると思いました。
これらのベンチマークの問題の大きな部分は、C#を書いているようにC++コードを書くことができず、代表的な結果が得られることを期待できることです(たとえば、C++で数千のメモリ割り当てを実行すると、ひどい数字が得られます)。
代わりに、私は少し慣用的なC++コードを作成し、提供された@WioryのC#コードと比較しました。 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);
}
実行時間(リリース):初期化:398µs(はい、それはマイクロ秒)、フィル:152ms
観察
C#実装を同じ1d配列実装に変更すると、Init:40ミリ秒、Fill:171ミリ秒、Total:211ミリ秒(C++はほぼ40%高速でした)。
C++で「高速」コードを設計および作成することは、どちらの言語で「通常」コードを作成することよりもはるかに困難です。
C++でパフォーマンスが低下するのは(おそらく)驚くほど簡単です。予約されていないベクターのパフォーマンスでそれを見ました。そして、このような落とし穴がたくさんあります。
C#のパフォーマンスは、実行時にすべてが進行していることを考えると、かなり驚くべきものです。そして、そのパフォーマンスは比較的簡単にアクセスできます。
C++とC#のパフォーマンスを比較した事例データ: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore
肝心なのは、C++を使用するとパフォーマンスをはるかに制御できることです。ポインターを使用しますか?参照?スタックメモリ?ヒープ?動的なポリモーフィズム、または静的なポリモーフィズム(テンプレート/ CRTP経由)を使用したvtableの実行時オーバーヘッドを排除しますか? C++では... er、toを自分で(およびそれ以上)選択し、理想的には解決するのがあなたが取り組んでいる問題に最適であるようにする必要があります。
上記の些細な例でも、パフォーマンスは大幅に向上しますが、アクセスするにはより多くの投資が必要であることがわかります。
私の経験では(両方の言語で多くの作業をしました)、C++と比較したC#の主な問題はメモリ消費量が多いことであり、それを制御する良い方法が見つかりませんでした。最終的に.NETソフトウェアの速度を低下させるのは、メモリ消費でした。
もう1つの要因は、JITコンパイラーは実行時に実行されるため、高度な最適化を実行する余裕がないことであり、エンドユーザーは時間がかかりすぎると気づくでしょう。一方、C++コンパイラには、コンパイル時に最適化を行う必要があるすべての時間があります。この要因は、メモリ消費量、IMHOよりもはるかに重要ではありません。
コンパイル時にポリモーフィックな決定を事前に決定できる場合、C++が依然として優位である(そして今後数年間はそうなる)特定のシナリオが発生します。
一般に、カプセル化と据え置きの意思決定は、コードをより動的にし、変化する要件に容易に適合させ、フレームワークとして使用しやすくするため、良いことです。これが、C#でのオブジェクト指向プログラミングの生産性が非常に高く、「一般化」という用語で一般化できる理由です。残念ながら、この種の一般化は実行時にコストがかかります。
通常、このコストは実質的ではありませんが、仮想メソッド呼び出しとオブジェクト作成のオーバーヘッドが違いを生むアプリケーションがあります(特に仮想メソッドはメソッド呼び出しのインライン化などの他の最適化を妨げるため)。これは、C++に大きな利点がある場所です。テンプレートを使用して、ランタイムにnoの影響を与えるが、必ずしもOOPよりもポリモーフィックではない異なる種類の一般化を実現できるからです。実際、OOPを構成するメカニズムはすべて、テンプレートテクニックとコンパイル時の解決のみを使用してモデル化できます。
そのような場合(そして確かに、それらは特別な問題のあるドメインに限定されることが多い)、C++はC#および同等の言語に対して勝ちます。
C++(またはC)を使用すると、データ構造をきめ細かく制御できます。少しいじりたい場合は、そのオプションがあります。 Java/.NETライブラリの内部データ構造を使用する大規模なJavaまたは.NETアプリ(OWB、 Visual Studio 2005 )は、荷物を持ち運びます。キューブに400 sessionsMB以上のRAMとBIDSを使用するOWBデザイナーセッション、または ETL が数百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++が5倍または10倍速い場合、特に操作を簡単にSIMDできる場合があります。
私はそれがあなたが求めていたものではないことを知っていますが、C#は多くの場合、C + +よりも速くwriteになります。これは商用設定で大きなボーナスです。
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++のrawポインターバージョンが付属していますC#よりも約2.1倍高速です。 C#プログラムは安全なコードのみを使用していることに注意してください。unsafe
キーワードを使用する前にC++でコーディングすることもできます。
誰かが私がC#に対して何かを持っていると思わないように、C#はおそらく私のお気に入りの言語だと言って締めくくります。これは、これまで出会った中で最も論理的で直感的で迅速な開発言語です。プロトタイピングはすべてC#で行います。 C#言語にはJavaよりも多くの小さな微妙な利点があります(はい、Microsoftがゲームに遅れて入り、おそらくJavaをコピーすることによってJavaの多くの欠点を修正する機会があったことは知っています)。 JavaのCalendar
クラスに乾杯しますか? MicrosoftがCLRと.NET JITterを最適化するために実際の努力を費やした場合、C#が真剣に引き継ぐ可能性があります。彼らはまだC#言語で多くのことを行っていなかったので、私は正直驚いています。コンパイラーの最適化を多用してフォローアップしてみませんか?たぶん私たち全員が請うなら。
>聞いたことから...
あなたの難しさは、聞いたことを信頼できるかどうかを判断することにあるようです。このサイトで返信を評価しようとすると、その難易度が繰り返されるだけです。
ここで人々が言うことは、あなたが最初に聞いたものよりも多かれ少なかれ信頼できるかどうかをどのように決定するつもりですか?
1つの方法は、証拠を求めることです。
誰かが「C#がC++よりも高速であることが証明されている領域がある」と主張するとき尋ねるwhy彼らはそれを言う、測定値を表示するように依頼し、プログラムを表示するように依頼します。時々、彼らは単に間違いを犯しただけでしょう。時には、彼らが真実であると示すことができる何かを共有するのではなく、単に意見を表明していることがわかります。
多くの場合、情報と意見は、人々が主張するものにまちまちであり、あなたはどちらがどれであるかを整理しなければなりません。たとえば、このフォーラムの返信から:
」 http://shootout.alioth.debian.org/ でベンチマークを実行します。これらは大部分が算術コードをテストするため、非常に懐疑的です。コードにまったく似ています。」
「これらは主に算術コードをテストします」の意味を本当に理解しているかどうかを自問し、著者が自分の主張が真実であることを実際に示しているかどうか自問してください。
」これはかなり役に立たないテストです。個々のプログラムがどれだけ最適化されているかに本当に依存するためです。それらの一部を4〜6倍以上高速化することができました。最適化されていないプログラム間の比較はかなりばかげています。」
著者が「そのうちのいくつかを4〜6倍以上高速化した」ことを実際に示しているかどうかを自問してみてください-それは簡単な主張です!
.NET言語は、C++コードと同じくらい、またはさらに高速になりますただし、C++コードはより一定のスループットを持ちます .NETランタイムは GC で一時停止する必要があるため、たとえ一時停止について非常に賢い場合でも。
したがって、一時停止することなく一貫して高速に実行する必要があるコードがある場合、ランタイムGCに細心の注意を払っていても、.NETはレイテンシある時点でを導入します。
これは非常に曖昧な質問であり、実際の決定的な答えはありません。
例えば;パフォーマンスは確かにはるかに優れているため、C#よりもC++で作成された3Dゲームをプレイしたいです。 (そして、私はXNAなどを知っていますが、それは本物に近づきません)。
一方、前述のとおり。必要なことをすばやく実行できる言語で開発し、必要に応じて最適化する必要があります。
「並外れて並列的な」問題の場合、C++でIntel TBBとOpenMPを使用すると、C#とTPLで行われた同様の(純粋な数学)問題と比較して、パフォーマンスが約10倍向上します。 SIMDはC#が競合できない分野の1つですが、TPLにはかなりのオーバーヘッドがあるという印象も受けました。
そうは言っても、マルチスレッドを使用して迅速に結果を得ることができるとわかっているパフォーマンス重視のタスクにのみC++を使用します。他のすべてについては、C#(および場合によってはF#)で十分です。
理論的には、長時間実行されるサーバータイプのアプリケーションの場合、JITでコンパイルされた言語は、ネイティブにコンパイルされた対応する言語よりも高速にmuchになります。 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#:
集中的なメモリアクセスを必要とするアプリケーション。通常、画像操作は、マネージド(C#)よりもアンマネージド環境(C++)で記述した方が適切です。ポインター演算を使用して最適化された内部ループは、C++での制御がはるかに簡単です。 C#では、同じパフォーマンスに近づくために、安全でないコードに頼る必要がある場合があります。
まあ、それは依存します。バイトコードがマシンコードに変換される場合(JITだけでなく)(プログラムを実行する場合を意味します)andGC アルゴリズムはメモリ全体を一度(理論的に)1回パスするだけでよいため、割り当て/割り当て解除はより高速になりますが、通常のmalloc/realloc/free C/C++呼び出しは呼び出しごとにオーバーヘッドを引き起こします(呼び出しオーバーヘッド、データ構造のオーバーヘッド、キャッシュミス;))。
したがって、理論的には可能です(他のGC言語でも)。
ほとんどのアプリケーションではC#で metaprogramming を使用できないという極端な欠点は、実際にはありません。ほとんどのプログラマーは、とにかく使用しないからです。
もう1つの大きな利点は、SQLが LINQ "extension"のように、コンパイラがデータベースへの呼び出しを最適化する機会を提供することです(言い換えると、コンパイラはLINQ全体を1つの "blob 「呼び出された関数がインライン化されているか、使用のために最適化されているバイナリですが、ここで推測しています)。
C#で書かれたアプリケーションが高速で実行されているだけでなく、C++で書かれたアプリケーションが高速で実行されていると思います(C++は古いだけでなく、UNIXも使用しています...)
-確かに質問は-そのことは何ですか、ユーザーと開発者は不満を言っています...
まあ、私見、C#の場合、非常に快適なUI、ライブラリの非常に素晴らしい階層、およびCLIのインターフェイスシステム全体があります。 C++の場合、テンプレート、ATL、COM、MFC、およびOpenGL、DirectXなどのコードを既に実行および実行しているShecの全体があります。 1秒で-強打!それが立ち往生しています)。
C#で非常にシンプルかつ高速にコードを書くこと(エラーの可能性を高めることを忘れないでください。C++の場合、開発者はメモリリークについて不満を言います。クラッシュ、DLL間の呼び出し、 "DLL地獄」-サポートと新しいライブラリによる置換ライブラリの問題...
プログラミング言語のスキルが高いほど、ソフトウェアの品質(および速度)が向上すると思います。
私はそれをこう言います:より速いコードを書くプログラマーは、現在のマシンを高速化するものについてより多くの情報を与えられたプログラマーであり、偶然にも、正確な低レベルで決定論的なことを可能にする適切なツールを使用するプログラマーです最適化テクニック。これらの理由から、これらの人々はC#ではなくC/C++を使用する人々です。私はこれを事実として述べるまで行きます。
間違っていなければ、C#テンプレートは実行時に決定されます。これは、C++のコンパイル時テンプレートよりも遅くなければなりません。
そして、非常に多くの他の人が言及した他のすべてのコンパイル時最適化を取り入れると、実際にはより速い速度を意味する安全性の欠如...
生の速度と最小メモリ消費の観点から、C++が明らかな選択だと思います。しかし、これはまた、コードの開発により多くの時間を費やし、メモリリークやnullポインタ例外の発生を防ぎます。
評決:
C#:より速い開発、より遅い実行
C++:開発が遅く、実行が高速です。
パフォーマンスの面では、C#とC++の間にいくつかの大きな違いがあります。
そのほか、プログラマーの能力も役割を果たします。私は、クラスが引数として値で渡されるところの悪い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;
}