it-swarm.com.de

Wie viel schneller ist C++ als C #?

Oder ist es jetzt umgekehrt?

Ich habe gehört, dass es einige Bereiche gibt, in denen C # schneller ist als C++, aber ich hatte noch nie den Mut, es selbst zu testen.

Ich dachte, jeder von euch könnte diese Unterschiede im Detail erklären oder mich an die richtige Stelle für Informationen dazu bringen.

206
Trap

Es gibt keinen strengen Grund, warum eine Bytecode-basierte Sprache wie C # oder Java, die eine JIT hat, nicht so schnell sein kann wie C++ - Code. Allerdings war C++ - Code lange Zeit deutlich schneller und auch heute noch in vielen Fällen. Dies liegt vor allem daran, dass die fortgeschrittenen JIT-Optimierungen kompliziert zu implementieren sind und die wirklich coolen erst jetzt eintreffen.

Daher ist C++ in vielen Fällen schneller. Dies ist jedoch nur ein Teil der Antwort. In den Fällen, in denen C++ tatsächlich schneller ist, handelt es sich um hochoptimierte Programme, bei denen erfahrene Programmierer den Code gründlich optimiert haben. Dies ist nicht nur sehr zeitaufwändig (und damit teuer), sondern führt in der Regel auch zu Fehlern aufgrund von Überoptimierungen.

Auf der anderen Seite wird Code in interpretierten Sprachen in späteren Versionen der Laufzeitumgebung (.NET CLR oder Java VM) schneller, ohne dass Sie etwas tun müssen. Und es gibt viele nützliche Optimierungen, die JIT-Compiler tun können, die in Sprachen mit Zeigern einfach unmöglich sind. Einige argumentieren auch, dass die Speicherbereinigung im Allgemeinen genauso schnell oder schneller sein sollte wie die manuelle Speicherverwaltung, und in vielen Fällen ist dies auch der Fall. Sie können dies in der Regel in C++ oder C implementieren und erreichen, aber es wird viel komplizierter und fehleranfälliger.

Wie Donald Knuth sagte, "vorzeitige Optimierung ist die Wurzel allen Übels". Wenn Sie wirklich sicher sind, dass Ihre Anwendung hauptsächlich aus sehr leistungskritischen Arithmetik besteht, und dass dies der Engpass sein wird, wird es in C++ sicherlich schneller sein, und Sie sind sicher, dass C++ nicht mit Ihrem anderen in Konflikt steht Voraussetzungen, gehen Sie für C++. Konzentrieren Sie sich in jedem anderen Fall zunächst auf die korrekte Implementierung Ihrer Anwendung in der Sprache, die für Sie am besten geeignet ist. Finden Sie dann Leistungsengpässe, wenn sie zu langsam läuft, und überlegen Sie, wie Sie den Code optimieren können. Im schlimmsten Fall müssen Sie möglicherweise über eine fremde Funktionsschnittstelle C-Code aufrufen, sodass Sie immer noch die Möglichkeit haben, kritische Teile in niedrigerer Sprache zu schreiben.

Denken Sie daran, dass es relativ einfach ist, ein korrektes Programm zu optimieren, aber es ist viel schwieriger, ein optimiertes Programm zu korrigieren.

Es ist unmöglich, tatsächliche Prozentsätze der Geschwindigkeitsvorteile anzugeben, es hängt weitgehend von Ihrem Code ab. In vielen Fällen ist die Implementierung der Programmiersprache nicht einmal der Engpass. Nehmen Sie die Benchmarks unter http://benchmarksgame.alioth.debian.org/ mit großer Skepsis, da diese weitgehend arithmetischen Code testen, der höchstwahrscheinlich Ihrem Code überhaupt nicht ähnelt.

296
Martin Probst

C # ist zwar nicht schneller, macht Sie aber schneller. Das ist die wichtigste Maßnahme für das, was ich tue. :)

175
mattlant

Es sind fünf Orangen schneller. Oder eher: Es kann keine (richtige) pauschale Antwort geben. C++ ist eine statisch kompilierte Sprache (es gibt jedoch auch eine profilgesteuerte Optimierung). C # wird mit Hilfe eines JIT-Compilers ausgeführt. Es gibt so viele Unterschiede, dass Fragen wie „wie viel schneller“ nicht beantwortet werden können, auch nicht durch Angabe von Größenordnungen.

76
Konrad Rudolph

Ich werde damit beginnen, einem Teil der akzeptierten (und positiv bewerteten) Antwort auf diese Frage zu widersprechen, indem ich Folgendes erkläre:

Es gibt viele Gründe, warum JITted-Code langsamer als ein ordnungsgemäß optimiertes C++ (oder eine andere Sprache ohne Laufzeitaufwand) ausgeführt wird Program, einschließlich:

  • rechenzyklen, die zur Laufzeit für JITting-Code aufgewendet werden, sind definitionsgemäß für die Verwendung bei der Programmausführung nicht verfügbar.

  • alle Hot-Pfade im JITter konkurrieren mit Ihrem Code um Anweisungen und Datencache in der CPU. Wir wissen, dass der Cache-Speicher in puncto Leistung dominiert, und Muttersprachen wie C++ haben definitionsgemäß keinen derartigen Konflikt.

  • das Zeitbudget eines Laufzeitoptimierers ist notwendigerweise viel stärker eingeschränkt als das eines Kompilierzeitoptimierers (wie ein anderer Kommentator darauf hinweist).

Fazit: Letztendlich können Sie will mit ziemlicher Sicherheit eine schnellere Implementierung in C++ erstellen, als Sie es in C # könnten.

Damit ist wie viel schneller wirklich nicht quantifizierbar, da es zu viele Variablen gibt: Task, Problemdomäne, Hardware, Implementierungsqualität und viele andere Faktoren. Sie haben Tests für Ihr Szenario ausgeführt, um den Leistungsunterschied zu ermitteln, und dann entscheiden, ob sich der zusätzliche Aufwand und die Komplexität lohnen.

Dies ist ein sehr langwieriges und komplexes Thema, aber der Vollständigkeit halber ist es erwähnenswert, dass der Laufzeitoptimierer von C # hervorragend ist und bestimmte dynamische Optimierungen zur Laufzeit ausführen kann, die C++ mit seiner Kompilierzeit nicht zur Verfügung stehen ( statischer Optimierer. Trotzdem liegt der Vorteil des Verfahrens der nativen Anwendung immer noch im tiefsten Bereich, aber der dynamische Optimierer ist der Grund für das oben angegebene "fast sicherlich" Qualifikationsmerkmal. 

-

Bezüglich der relativen Leistung waren ich auch durch die Zahlen und Diskussionen, die ich in einigen anderen Antworten sah, beunruhigt. Ich dachte, ich würde einspringen und gleichzeitig die oben gemachten Aussagen unterstützen.

Ein großer Teil des Problems bei diesen Benchmarks ist, dass Sie keinen C++ - Code schreiben können, als würden Sie C # schreiben, und davon ausgehen, dass Sie repräsentative Ergebnisse erhalten (wenn Sie z. B. Tausende von Speicherzuordnungen in C++ ausführen, werden Sie schreckliche Zahlen erhalten.)

Stattdessen habe ich etwas mehr idiomatischen C++ - Code geschrieben und mit dem bereitgestellten C # -Code @Wiory verglichen. Die zwei wichtigsten Änderungen, die ich am C++ - Code vorgenommen habe, waren:

1) verwendeter Vektor :: reserve ()

2) das 2d-Array auf 1d abgeflacht, um eine bessere Cache-Lokalität zu erreichen (zusammenhängender Block)

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);
}

Laufzeit (Release): 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);
}

Laufzeit (Release): Init: 398µs (ja, das sind Mikrosekunden), Füllung: 152ms

Gesamtlaufzeiten: C #: 289ms, C++ 152ms (ca. 90% schneller)

Beobachtungen

  • Wenn Sie die C # -Implementierung in dieselbe 1d-Arrayimplementierung ändern Ergab Init: 40ms, Fill: 171ms, Gesamt: 211ms (C++ war noch fast 40% schneller).

  • Es ist viel schwieriger, "schnellen" Code in C++ zu entwerfen und zu schreiben als "normalen" Code in beiden Sprachen.

  • Es ist (vielleicht) erstaunlich einfach, schlechte Leistung in C++ zu erzielen. Wir haben das mit uneingeschränkter Leistung von Vektoren gesehen. Und es gibt viele Fallstricke wie diese.

  • Die Leistung von C # ist ziemlich erstaunlich, wenn Sie alles zur Laufzeit betrachten. Und diese Leistung ist vergleichsweise einfach zu bedienen.

  • Weitere anekdotische Daten zum Vergleich der Leistung von C++ und C #: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore

Unter dem Strich haben Sie mit C++ viel mehr Kontrolle über die Leistung. Möchten Sie einen Zeiger verwenden? Eine Referenz? Speicher stapeln? Haufen? Dynamischer Polymorphismus oder Eliminierung des Laufzeit-Overheads einer vtable mit statischem Polymorphismus (über Templates/CRTP)? In C++ müssen Sie ... äh, dorthinalle diese Entscheidungen (und mehr) selbst treffen, idealerweise, damit Ihre Lösung das angesprochene Problem am besten anspricht.

Fragen Sie sich, ob Sie diese Kontrolle wirklich wollen oder brauchen, denn selbst für das obige triviale Beispiel können Sie feststellen, dass die Performance zwar erheblich verbessert wird, jedoch eine tiefere Investition erforderlich ist.

59
U007D

Nach meiner Erfahrung (und ich habe viel mit beiden Sprachen gearbeitet) ist das Hauptproblem bei C # im Vergleich zu C++ der hohe Speicherverbrauch, und ich habe keinen guten Weg gefunden, es zu steuern. Es war der Speicherverbrauch, der .NET-Software letztendlich verlangsamen würde.

Ein weiterer Faktor ist, dass der JIT-Compiler sich nicht zu viel Zeit für erweiterte Optimierungen leisten kann, da er zur Laufzeit ausgeführt wird und der Endbenutzer dies bemerken würde, wenn er zu viel Zeit in Anspruch nimmt. Auf der anderen Seite hat ein C++ - Compiler alle Zeit, um Optimierungen zur Kompilierzeit vorzunehmen. Dieser Faktor ist viel weniger bedeutsam als der Speicherverbrauch, IMHO.

55

Ein besonderes Szenario, in dem C++ immer noch die Oberhand hat (und wird es auf Jahre hinaus bleiben), tritt auf, wenn polymorphe Entscheidungen zur Kompilierzeit vorbestimmt werden können.

Generell ist Kapselung und verzögerte Entscheidungsfindung eine gute Sache, da der Code dynamischer wird, einfacher an sich ändernde Anforderungen angepasst werden kann und als Framework einfacher zu verwenden ist. Daher ist die objektorientierte Programmierung in C # sehr produktiv und kann unter dem Begriff "Generalisierung" verallgemeinert werden. Leider ist diese spezielle Art der Verallgemeinerung zur Laufzeit mit Kosten verbunden.

Normalerweise sind diese Kosten nicht wesentlich, aber es gibt Anwendungen, bei denen der Aufwand für virtuelle Methodenaufrufe und die Objekterstellung einen Unterschied ausmachen kann (insbesondere da virtuelle Methoden andere Optimierungen wie das Inlining von Methodenaufrufen verhindern). Hier hat C++ einen großen Vorteil, da Sie mit Hilfe von Templates eine andere Art der Generalisierung erreichen können, die sich auf die Laufzeit no auswirkt, jedoch nicht unbedingt weniger polymorph als OOP ist. Tatsächlich können alle Mechanismen, aus denen OOP besteht, nur unter Verwendung von Schablonentechniken und Auflösung der Kompilierzeit modelliert werden.

In solchen Fällen (und zwar sind diese häufig auf spezielle Problembereiche beschränkt), gewinnt C++ gegen C # und vergleichbare Sprachen.

32
Konrad Rudolph

Mit C++ (oder C für diese Angelegenheit) haben Sie eine genaue Kontrolle über Ihre Datenstrukturen. Wenn Sie sich zwicken wollen, haben Sie diese Option. Große verwaltete Java- oder .NET-Apps (OWB, Visual Studio 2005 ), die die internen Datenstrukturen der Java/.NET-Bibliotheken verwenden, tragen das Gepäck mit sich. Ich habe OWB-Designersitzungen mit über 400 MB RAM und BIDS für Cube oder ETL Design gesehen, die auch in die 100er von MB kamen.

Bei einer vorhersehbaren Arbeitslast (wie bei den meisten Benchmarks, die einen Prozess häufig wiederholen) kann eine JIT zu Code führen, der so gut optimiert ist, dass es keinen praktischen Unterschied gibt.

IMO bei großen Anwendungen besteht der Unterschied nicht so sehr in der JIT als in den Datenstrukturen, die der Code selbst verwendet. Wenn eine Anwendung speicherintensiv ist, erhalten Sie eine weniger effiziente Cache-Nutzung. Cache-Misses auf modernen CPUs sind ziemlich teuer. Wo C oder C++ wirklich gewinnen, können Sie die Verwendung von Datenstrukturen optimieren, um mit dem CPU-Cache gut zu spielen.

Für Grafiken ist die Standardklasse C # Graphics viel langsamer als GDI, auf die über C/C++ zugegriffen wird. Ich weiß, dass dies nichts mit der Sprache an sich zu tun hat, mehr mit der gesamten .NET-Plattform, aber mit Grafiken wird dem Entwickler als GDI - Ersatz angeboten, und seine Leistung ist so schlecht, dass ich es nicht einmal wagen würde, Grafiken damit zu erstellen.

Wir verwenden einen einfachen Benchmark, um zu sehen, wie schnell eine Grafikbibliothek ist. Das Zeichnen zufälliger Linien in einem Fenster. C++/GDI ist immer noch mit 10000 Zeilen zufrieden, während C #/Graphics in Echtzeit Schwierigkeiten hat, 1000 zu erreichen.

18
QBziZ

Die Garbage Collection ist der Hauptgrund dafür, dass Java # NICHT für Echtzeitsysteme verwendet werden kann.

  1. Wann wird der GC stattfinden?

  2. Wie lange wird es dauern?

Das ist nicht deterministisch.

12
asdfgh

Wir mussten feststellen, ob C # in der Leistung mit C++ vergleichbar war, und ich schrieb dazu einige Testprogramme (unter Verwendung von Visual Studio 2005 für beide Sprachen). Es stellte sich heraus, dass C # ohne Garbage Collection und nur unter Berücksichtigung der Sprache (nicht des Frameworks) im Wesentlichen die gleiche Leistung wie C++ aufweist. Die Speicherzuordnung ist in C # viel schneller als in C++, und C # hat einen geringfügigen Rand in der Deterministik, wenn die Datengröße über die Grenzen der Cache-Zeilen hinaus ansteigt. All dies musste jedoch letztendlich bezahlt werden, und es gibt enorme Kosten in Form nicht deterministischer Leistungstreffer für C # aufgrund von Speicherbereinigung.

11
ILoveFortran

Wie üblich hängt es von der Anwendung ab. Es gibt Fälle, in denen C # wahrscheinlich vernachlässigbar langsamer ist, und in anderen Fällen, in denen C++ 5 oder 10 Mal schneller ist, insbesondere in Fällen, in denen Operationen leicht SIMD-fähig sind.

9
Dark Shikari

Ich weiß, es ist nicht das, was Sie gefragt haben, aber C # ist oft schneller als write als C++, was in kommerziellen Umgebungen ein großer Bonus ist.

9
Kramii

C/C++ kann in Programmen, in denen es entweder große Arrays oder eine starke Schleife/Wiederholung über Arrays (beliebiger Größe) gibt, erheblich bessere Ergebnisse erzielen. Dies ist der Grund dafür, dass Grafiken in C/C++ im Allgemeinen viel schneller sind, da fast allen Grafikoperationen umfangreiche Array-Operationen zugrunde liegen. .NET ist aufgrund der zahlreichen Sicherheitsüberprüfungen bei Array-Indexierungsoperationen bekanntermaßen langsam. Dies gilt insbesondere für mehrdimensionale Arrays (und ja, rechteckige C # -arrays sind sogar langsamer als gezackte C # -arrays.

Die Boni von C/C++ sind am ausgeprägtesten, wenn Sie direkt bei Zeigern bleiben und Boost, std::vector und andere High-Level-Container sowie inline jede mögliche kleine Funktion vermeiden. Verwenden Sie möglichst alte Arrays der alten Schule. Ja, Sie benötigen mehr Codezeilen, um dasselbe zu erreichen wie in Java oder C #, wenn Sie Container auf hoher Ebene vermeiden. Wenn Sie ein Array mit dynamischer Größe benötigen, müssen Sie nur daran denken, Ihren new T[] mit einer entsprechenden delete[]-Anweisung (oder verwenden Sie std::unique_ptr) zu koppeln. Im Gegenzug können Sie sich jedoch vom Aufwand für verwalteten Speicher/Garbage-Collector befreien, der leicht 20% oder mehr der Ausführungszeit von stark objektorientierten Programmen in Java und .NET sowie von solchen, die verwaltet werden, ausmachen kann Kosten für die Indexierung des Speicherarrays. C++ - Apps können in bestimmten Fällen auch von einigen einfachen Compiler-Switches profitieren.

Ich bin ein erfahrener Programmierer in C, C++, Java und C #. Ich hatte kürzlich die seltene Gelegenheit, das gleiche algorithmische Programm in den letzten 3 Sprachen zu implementieren. Das Programm hatte viele mathematische und mehrdimensionale Array-Operationen. Ich habe dies in allen 3 Sprachen stark optimiert. Die Ergebnisse waren typisch für das, was ich normalerweise in weniger strengen Vergleichen sehe: Java war etwa 1,3x schneller als C # (die meisten JVMs sind mehr optimiert als die CLR), und die C++ - Version des Rohzeigers war etwa 2,1x schneller als C #. Beachten Sie, dass das C # -Programm nur sicheren Code verwendet hat. Meines Erachtens könnten Sie ihn auch in C++ programmieren, bevor Sie das Schlüsselwort unsafe verwenden.

Damit niemand denkt, dass ich etwas gegen C # habe, möchte ich sagen, dass C # wahrscheinlich meine Lieblingssprache ist. Es ist die logischste, intuitivste und schnellste Entwicklungssprache, die ich bisher gesehen habe. Ich mache alle meine Prototypen in C #. Die C # -Sprache hat viele kleine, subtile Vorteile gegenüber Java (ja, ich weiß, Microsoft hatte die Möglichkeit, viele der Nachteile von Java zu beheben, indem er zu spät ins Spiel kam und wahrscheinlich Java kopiert). Jemanden auf Javas Calendar-Klasse anstoßen? Wenn Microsoft jemals große Anstrengungen unternimmt, um CLR und .NET JITter zu optimieren, könnte C # ernsthaft die Kontrolle übernehmen. Ich bin ehrlich überrascht, dass sie es noch nicht getan haben - sie haben so viele Dinge in der C # -Sprache richtig gemacht. Warum sollten Sie nicht mit den Compiler-Optimierungen konfrontiert werden? Vielleicht, wenn wir alle betteln.

7
Special Sauce

> Von dem, was ich gehört habe ...

Ihre Schwierigkeit scheint darin zu liegen, zu entscheiden, ob das, was Sie gehört haben, glaubwürdig ist, und diese Schwierigkeit wird nur wiederholt, wenn Sie versuchen, die Antworten auf dieser Website zu bewerten.

Wie wollen Sie entscheiden, ob die Dinge, die die Leute hier sagen, mehr oder weniger glaubwürdig sind als das, was Sie ursprünglich gehört haben?

Eine Möglichkeit wäre, nach evidence zu fragen.

Wenn jemand behauptet, "gibt es einige Bereiche, in denen sich C # als schneller erweist als C++" frag sie warum sie sagen, dass sie bitten, Ihnen Messungen zu zeigen, bitten Sie sie, Ihnen Programme zu zeigen. Manchmal haben sie einfach einen Fehler gemacht. Manchmal werden Sie feststellen, dass sie nur eine Meinung äußern, anstatt etwas zu teilen, das sie als wahr beweisen können.

Oft werden Informationen und Meinungen in das, was die Leute behaupten, vermischt, und Sie müssen versuchen, herauszufinden, welches das ist. Zum Beispiel aus den Antworten in diesem Forum:

  • "Nehmen Sie die Benchmarks unter http://shootout.alioth.debian.org/ Mit großer Skepsis, als Diese testen weitgehend arithmetischen Code....) höchstwahrscheinlich überhaupt nicht mit Ihrem Code vergleichbar. "

    Fragen Sie sich, ob Sie wirklich verstehen, was "diese weitgehend test Arithmetischen Code" bedeutet, und dann Sich fragen, ob der Autor .__ Ihnen tatsächlich gezeigt hat, dass seine Behauptung istwahr.

  • "Das ist ein ziemlich nutzloser Test, da es wirklich davon abhängt, wie gut Die einzelnen Programme optimiert wurden . Ich habe es geschafft, Einige von ihnen 4-6 Mal oder mehr zu beschleunigen , Damit wird klargestellt, dass der Vergleich zwischen nicht optimierten Programmen ziemlich dumm ist. "

    Fragen Sie sich, ob der Autor Ihnen tatsächlich gezeigt hat, dass er es geschafft hat. Um einige von ihnen um 4-6 mal oder mehr zu beschleunigen, ist dies ein einfacher Anspruch!

6
Isaac Gouy

.NET-Sprachen können genauso schnell sein wie C++ - Code oder sogar schneller C++ - Code hat jedoch einen konstanteren Durchsatz, da die .NET-Laufzeit für GC anhalten muss, selbst wenn dies der Fall ist sehr klug über seine Pausen.

Wenn Sie also Code haben, der konstant ohne Pause laufen muss, führt .NET eine Latenzzeit irgendwann ein, auch wenn Sie mit dem Laufzeit-GC sehr vorsichtig sind.

6
Florian Doyon

Es ist eine äußerst vage Frage ohne echte endgültige Antworten.

Zum Beispiel; Ich spiele lieber 3D-Spiele, die in C++ erstellt wurden, als in C #, da die Leistung sicherlich viel besser ist. (Und ich kenne XNA usw., aber es kommt der wirklichen Sache auf keinen Fall nahe).

Andererseits, wie zuvor erwähnt; Sie sollten sich in einer Sprache entwickeln, in der Sie schnell tun können, was Sie möchten, und dann gegebenenfalls optimieren.

5
David The Man

Bei "peinlich parallelen" Problemen habe ich bei der Verwendung von Intel TBB und OpenMP unter C++ eine etwa zehnfache Leistungssteigerung im Vergleich zu ähnlichen (reinen mathematischen) Problemen mit C # und TPL festgestellt. SIMD ist ein Bereich, in dem C # nicht mithalten kann, aber ich habe auch den Eindruck, dass TPL einen erheblichen Overhead hat.

Allerdings verwende ich C++ nur für leistungskritische Aufgaben, bei denen ich weiß, dass ich Multithreading ausführen kann und schnell Ergebnisse erzielen kann. Für alles andere ist C # (und gelegentlich F #) einfach in Ordnung.

5
Dmitri Nesteruk

Theoretisch kann eine JIT-kompilierte Sprache für eine lange laufende Serveranwendung viel schneller werden als eine nativ kompilierte Gegenstelle. Da die kompilierte JIT-Sprache in der Regel zuerst zu einer relativ einfachen Zwischensprache kompiliert wird, können Sie viele der hochstufigen Optimierungen bereits zur Kompilierzeit durchführen. Der große Vorteil ist, dass die JIT weiterhin Codeabschnitte im laufenden Betrieb neu kompilieren kann, da immer mehr Daten zur Verwendung der Anwendung abgerufen werden. Es kann die gängigsten Codepfade so anordnen, dass die Verzweigungsvorhersage so oft wie möglich erfolgreich sein kann. Es kann separate Codeblöcke neu anordnen, die häufig zusammen aufgerufen werden, um beide im Cache zu halten. Es kann mehr Aufwand für die Optimierung der inneren Schleifen aufwenden.

Ich bezweifle, dass dies von .NET oder einer der JREs gemacht wird, aber es wurde bereits während meines Studiums recherchiert. Daher ist es nicht unvernünftig zu glauben, dass diese Dinge irgendwann bald in die Realität gelangen werden .

4
Eclipse

Ich habe vector in C++ und C # -Äquivalent - List und einfachen 2d-Arrays getestet.

Ich verwende Visual C #/C++ 2010 Express-Editionen. Beide Projekte sind einfache Konsolenanwendungen. Ich habe sie im Standard- (keine benutzerdefinierten Einstellungen) Release- und Debug-Modus getestet C # -Listen laufen schneller auf meinem PC, die Array-Initialisierung ist auch in C # schneller, mathematische Operationen sind langsamer.

Ich verwende Intel Core2Duo [email protected], C # - .NET 4.0.

Ich weiß, dass die Vektorimplementierung sich von der C # -Liste unterscheidet, aber ich wollte nur Sammlungen testen, die ich zum Speichern meiner Objekte verwenden würde (und Index-Accessor verwenden kann).

Natürlich müssen Sie den Speicher löschen (sagen wir für jede Verwendung von new), aber ich wollte den Code einfach halten.

C++ - Vektortest :

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 # Listentest:

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++ - Array:

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 # -Array:

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);

}

Zeit: (Release/Debug)

C++

  • 600/606 ms Array-Init,
  • 200/270 ms Feldfüllung,
  • 1sec/13sec Vektor Init & Fill.

(Ja, 13 Sekunden, ich habe immer Probleme mit Listen/Vektoren im Debug-Modus.)

c #:

  • 20/20 ms Array-Init,
  • 403/440 ms Feldfüllung,
  • 710/742 ms liste init & fill auf.
4
Wiory

Anwendungen, die intensiven Speicherzugriff erfordern, z. In der nicht verwalteten Umgebung (C++) ist die Bildmanipulation normalerweise besser als die verwaltete (C #). Optimierte innere Schleifen mit Zeigerarithmetik sind in C++ viel einfacher zu kontrollieren. In C # müssen Sie möglicherweise auf unsicheren Code zurückgreifen, um die gleiche Leistung zu erreichen.

4
Kalle

Es hängt davon ab. Wenn der Bytecode in Maschinencode übersetzt wird (und nicht nur in JIT) (ich meine, wenn Sie das Programm ausführen) und Wenn Ihr Programm viele Zuordnungen/Deallocations verwendet, könnte es schneller sein, weil GC algorithm benötigt nur einmal (theoretisch) einen Durchlauf durch den gesamten Speicher, aber normale malloc/realloc/free C/C++ - Aufrufe verursachen bei jedem Aufruf einen Overhead (Call-Overhead, Datenstruktur-Overhead, Cache-Misses;)).

Es ist also theoretisch möglich (auch für andere GC-Sprachen).

Ich sehe nicht den extremen Nachteil, die Metaprogrammierung mit C # für die meisten Anwendungen nicht verwenden zu können, da die meisten Programmierer es sowieso nicht verwenden.

Ein weiterer großer Vorteil ist, dass die SQL wie die Erweiterung " LINQ " dem Compiler die Möglichkeit bietet, Aufrufe von Datenbanken zu optimieren (mit anderen Worten, der Compiler könnte die gesamte LINQ zu einer "blob" - Binärdatei kompilieren Die aufgerufenen Funktionen sind inline oder für Ihre Verwendung optimiert, aber ich spekuliere hier.

3
Quonux

Wenn ich mich nicht irre, werden C # -Vorlagen zur Laufzeit bestimmt. Dies muss langsamer sein als Kompilierzeitvorlagen von C++. 

Und wenn Sie alle anderen Kompilierzeitoptimierungen in Betracht ziehen, die von so vielen anderen erwähnt wurden, sowie die mangelnde Sicherheit, die tatsächlich mehr Geschwindigkeit bedeutet ...

Ich würde sagen, dass C++ die offensichtliche Wahl ist, was die Rohgeschwindigkeit und den minimalen Speicherverbrauch angeht. Dies bedeutet jedoch auch mehr Zeit, den Code zu entwickeln und sicherzustellen, dass kein Speicherplatz verloren geht oder Nullzeigerausnahmen verursacht werden.

Urteil:

  • C #: Schnellere Entwicklung, langsamerer Lauf

  • C++: Langsame Entwicklung, schnellerer Lauf.

2
HumbleWebDev

Ich nehme an, es gibt in C # geschriebene Anwendungen, die schnell ausgeführt werden, und es gibt auch mehr von C++ geschriebene Anwendungen, die schnell ausgeführt werden (gut C++ nur älter ... und auch UNIX nehmen ...).
- Die Frage ist in der Tat - was ist das, worüber sich Benutzer und Entwickler beschweren ...
Nun, IMHO, im Falle von C # haben wir eine sehr komfortable Benutzeroberfläche, eine sehr schöne Hierarchie von Bibliotheken und ein ganzes Schnittstellensystem der CLI. Im Falle von C++ haben wir Vorlagen, ATL, COM, MFC und ganzes Shebang von bereits geschriebenem und laufendem Code wie OpenGL, DirectX usw. ... Entwickler beschweren sich bei C # (das Programm läuft schnell, und in einer Sekunde - bang!.
Um Code in C # sehr einfach und schnell zu schreiben (nicht zu vergessen, dass dies auch die Fehlerwahrscheinlichkeit erhöht. Bei C++ klagen Entwickler über Speicherlecks, - Quetschungen, Aufrufe zwischen DLLs sowie " DLL Hell "- Problem mit Support- und Ersatzbibliotheken durch neuere ...
Ich denke, je mehr Fähigkeiten Sie in der Programmiersprache haben, desto mehr Qualität (und Geschwindigkeit) wird Ihre Software charakterisieren.

2
bgee

Ich würde es so sagen: Programmierer, die schnelleren Code schreiben, sind die, die besser darüber informiert sind, was die aktuellen Maschinen beschleunigt, und sie sind übrigens auch die, die ein geeignetes Werkzeug verwenden, das präzise Low-Level- und Deterministik-Werte zulässt Optimierungstechniken. Aus diesen Gründen verwenden diese Personen C/C++ anstelle von C #. Ich würde so weit gehen, dies als Tatsache zu sagen.

2
Johan Boulé

> Die Antworten müssen doch irgendwo sein, oder? :)

Ähm nein.

Wie in mehreren Antworten angemerkt wurde, ist die Frage in einer Weise unterbestimmt , die Fragen zur Beantwortung einlädt, keine Antworten. Um nur einen Weg zu gehen:

Und welche Programme dann? Welche maschine Welches Betriebssystem? Welcher Datensatz?

1
Isaac Gouy

In Bezug auf die Leistung gibt es einige wesentliche Unterschiede zwischen C # und C++:

  • C # ist GC/Heap-basiert. Die Zuordnung und der GC selbst sind als die Nichtlokalität des Speicherzugriffs überlastet
  • C++ - Optimierer sind im Laufe der Jahre sehr gut geworden. JIT-Compiler können nicht dasselbe Niveau erreichen, da sie nur eine begrenzte Kompilierungszeit haben und den globalen Geltungsbereich nicht sehen

Daneben spielt auch die Programmierkompetenz eine Rolle. Ich habe schlechten C++ - Code gesehen, in dem Klassen überall als Argument als Wert übergeben wurden. Sie können es in C++ sogar noch schlimmer machen, wenn Sie nicht darauf achten.

0
gast128

Es hängt wirklich davon ab, was Sie in Ihrem Code erreichen möchten. Ich habe gehört, dass es nur eine Sache der urbanen Legende ist, dass es einen Leistungsunterschied zwischen VB.NET, C # und verwaltetem C++ gibt. Ich habe jedoch, zumindest im Vergleich von Strings, festgestellt, dass C++ die Hose von C # besiegt, was wiederum die Hose von VB.NET schlägt.

Ich habe keinesfalls einen erschöpfenden Vergleich der algorithmischen Komplexität zwischen den Sprachen vorgenommen. Ich verwende auch nur die Standardeinstellungen in jeder der Sprachen. In VB.NET verwende ich Einstellungen, um die Deklaration von Variablen usw. zu verlangen. Hier ist der Code, den ich für verwaltetes C++ verwende: (Wie Sie sehen, ist dieser Code ziemlich einfach). Ich verwende dasselbe in den anderen Sprachen in Visual Studio 2013 mit .NET 4.6.2.

#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;
}
0
Charles Owen