Frage

Oder ist es jetzt umgekehrt?

Nach allem, was ich gehört habe, gibt es einige Bereiche, in denen sich C# als schneller als C++ erweist, aber ich hatte nie den Mut, es selbst zu testen.

Ich dachte, jemand von Ihnen könnte diese Unterschiede im Detail erklären oder mich an die richtige Stelle für Informationen hierzu verweisen.

War es hilfreich?

Lösung

Es gibt keinen strengen Grund, warum eine Bytecode-basierte Sprache wie C # oder Java, die eine JIT hat nicht so schnell wie C ++ Code sein kann. Jedoch C ++ Code verwendete deutlich schneller für eine lange Zeit zu sein, und auch heute noch in vielen Fällen. Dies ist vor allem auf die weiter fortgeschrittenen JIT-Optimierungen zu implementieren kompliziert sind und die wirklich cool hinzukommen erst jetzt.

So C ++ schneller ist, in vielen Fällen. Aber das ist nur ein Teil der Antwort. Die Fälle, in denen C ++ ist tatsächlich schneller, sind hoch optimierte Programme, in denen Experten Programmierer die Hölle aus dem Code gründlich optimiert. Dies ist nicht nur sehr zeitaufwendig (und damit teuer), sondern führt auch häufig zu Fehlern aufgrund von über Optimierungen.

Auf der anderen Seite, Code in interpretierten Sprachen wird schneller in späteren Versionen der Common Language Runtime (CLR .NET oder Java VM), ohne dass Sie etwas zu tun. Und es gibt eine Menge nützlicher Optimierungen JIT-Compiler tun können, die mit Zeigern in Sprachen einfach nicht möglich sind. einige argumentieren auch, dass die Garbage Collection im Allgemeinen so schnell oder schneller als manuelle Speicherverwaltung sein sollte, und in vielen Fällen ist es. Sie können all dies in C ++ oder C im Allgemeinen implementieren und erreichen, aber es wird viel komplizierter und fehleranfällig sein.

Wie Donald Knuth sagte: „vorzeitige Optimierung ist die Wurzel aller Übel“. Wenn Sie wirklich sicher ist, dass Ihre Anwendung hauptsächlich aus sehr leistungskritischen Arithmetik bestehen wird, und dass es der Engpass sein, und es ist sicherlich schneller in C ++ sein werde, und Sie sind sicher, dass C ++ nicht mit dem anderen in Konflikt steht Anforderungen, gehen Sie für C ++. In jedem anderen Fall, konzentrieren sich auf die erste Anwendung richtig in welcher Sprache auch immer Ihnen am besten passt Implementierung, dann Performance-Engpässe finden, wenn es zu langsam läuft, und dann darüber nachdenken, wie Sie den Code zu optimieren. Im schlimmsten Fall müssen Sie möglicherweise durch eine Fremd Funktion Schnittstelle zum C-Code rufen, so dass Sie immer noch die Möglichkeit haben, kritische Teile in der unteren Ebene Sprache zu schreiben.

Beachten Sie, dass es relativ einfach, ein richtiges Programm zu optimieren, aber viel schwieriger, ein optimiertes Programm zu korrigieren.

tatsächlichen Prozentsatz der Geschwindigkeitsvorteile zu geben ist unmöglich, es hängt weitgehend von Ihrem Code. In vielen Fällen ist die Programmiersprache Umsetzung nicht einmal der Engpass. Nehmen Sie die Benchmarks unter http://benchmarksgame.alioth.debian.org/ mit viel Skepsis , da dieser arithmetischen Code weitgehend testen, die zu Ihrem Code höchstwahrscheinlich nicht ähnlich ist, überhaupt nicht.

Andere Tipps

C # kann nicht schneller, aber es macht SIE / ME schneller. Das ist die wichtigste Maßnahme für das, was ich tue. :)

Es ist fünf Orangen schneller. Oder besser gesagt: es kann keine (korrekte) Decke Antwort sein. C ++ ist eine statisch kompilierte Sprache (aber dann gibt es Profil geführt Optimierung, auch), C # läuft durch einen JIT-Compiler unterstützt. Es gibt so viele Unterschiede, die Fragen wie „wie viel schneller“, kann nicht beantwortet werden, auch nicht um Größenordnung zu geben.

Ich werde von nicht einverstanden mit einem Teil der akzeptiert (und gut upvoted) Antwort auf diese Frage mit der Feststellung beginnen:

Es gibt tatsächlich viele Gründe, warum JITted Code langsamer als ein richtig optimiert C ++ ausgeführt wird (oder eine andere Sprache ohne Laufzeit-Overhead) Programm mit:

  • Rechenzyklen auf JITting Code zur Laufzeit ausgegeben sind definitionsgemäß nicht verfügbar für den Einsatz in der Programmausführung.

  • alle heißen Pfade im Jitters werden mit dem Code für Befehls- und Daten-Cache-Speicher in der CPU konkurrieren. Wir wissen, dass Cache dominiert, wenn es um Leistung und Muttersprachen wie C ++ kommt nicht über diese Art des Anstoßes, per Definition.

  • Ein Laufzeit Optimierer Zeitbudget ist unbedingt viel eingeschränkteren als der einen Compiler-Optimierer (wie ein anderer Kommentator wies darauf hin)

Fazit: Letztlich Sie wird fast sicher in der Lage sein, eine schnellere Implementierung in C ++ zu erstellen, als Sie könnte in C #

.

Nun, mit dieser sagte, , wie viel schneller wirklich nicht quantifizierbar ist, da es zu viele Variablen sind: die Aufgabe, Problembereich, Hardware, Qualität der Implementierungen und viele andere Faktoren. Sie werden von Ihrem Szenario laufen Tests haben die den Unterschied in der Leistung zu bestimmen, und dann entscheiden, ob es sich lohnt, die der zusätzliche Aufwand und die Komplexität.

Dies ist ein sehr langes und komplexes Thema, aber ich glaube, es lohnt mich für die die Vollständigkeit halber erwähnt werden, dass C # 's Laufzeit-Optimierer ist ausgezeichnet, und ist in der Lage bestimmte dynamische Optimierungen zur Laufzeit auszuführen, die in C ++ mit seiner Kompilierung einfach nicht verfügbar sind -Zeit (statisch) Optimierer. Auch damit ist der Vorteil noch typischerweise tief in der nativen Anwendung des Gerichts, sondern der dynamische Optimierer ist der Grund für die „ fast auf jeden Fall“ Qualifier oben.

-

Im Hinblick auf die relative Leistung, ich wurde auch von den Zahlen und Diskussionen gestört ich in einigen anderen Antworten sah, so dachte ich, ich läuten würde und zugleich bieten eine gewisse Unterstützung für die Aussagen ich oben gemacht habe .

Ein großer Teil des Problems mit dem Benchmarks, die Sie nicht C schreiben können ++ Code, als ob Sie C # geschrieben haben und erwarten repräsentative Ergebnisse zu erhalten (z. B. Tausende von Speicherzuordnungen in C ++ durchführen werden Ihnen schreckliche Zahlen geben. )

Stattdessen schrieb ich etwas mehr idiomatischen C ++ Code und im Vergleich gegenüber der C # -Code @Wiory zur Verfügung gestellt. Die beiden wichtigsten Änderungen, die ich an den C ++ Code vorgenommen wurden:

1) verwendet vector :: Reserve ()

2) abgeflachte den 2D-Array bis 1d besser Cache Ort (zusammenhängender Block)

zu erreichen

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, geben Sie bitte: 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 Mikrosekunden), Fill: 152ms

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

Beobachtungen

  • Ändern der C # -Implementierung zu derselben 1D-Array Umsetzung Init ergab: 40 ms, geben Sie bitte: 171ms, Total: 211ms ( war C ++ noch fast 40% schneller ).

  • Es ist viel schwieriger zu entwerfen und "schnell" Code in C ++ zu schreiben, als es ist "normalen" Code in jeder Sprache zu schreiben.

  • Es ist (vielleicht) erstaunlich einfach eine schlechte Leistung in C ++ zu erhalten; wir sahen, dass mit unreserved Vektoren Leistung. Und es gibt viele Gefahren wie diese.

  • C # 's Leistung ist ziemlich erstaunlich, wenn man alle berücksichtigen, die zur Laufzeit vor sich geht. Und dass die Leistung ist vergleichsweise leicht zu Zugang.

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

Das Endergebnis ist, dass C ++ gibt Ihnen viel mehr Kontrolle über die Leistung. Wollen Sie einen Zeiger benutzen? Eine Referenz? Stapelspeicher? Haufen? Dynamische Polymorphismus oder eliminieren, die Laufzeit-Overhead eines vtable mit statischen Polymorphismus (via templates / CRTP)? In C ++ müssen Sie ... äh, bekommen machen all diese Entscheidungen (und mehr) selbst, am besten so, dass Ihre Lösung am besten befasst sich mit dem Problem, das Sie Angriff zu nehmen.

Fragen Sie sich, ob Sie wirklich wollen, oder dass die Kontrolle benötigen, denn auch für das triviale Beispiel oben können Sie sehen, dass, obwohl es eine deutliche Verbesserung der Performance ist es eine tieferen Investitionen Zugang erfordert.

Nach meiner Erfahrung (und ich habe viel mit beiden Sprachen gearbeitet), das Hauptproblem mit C # im Vergleich zu C ++ ist ein hoher Speicherverbrauch, und ich habe nicht eine gute Art und Weise zu steuern, es gefunden. Es war der Speicherverbrauch, die schließlich nach unten .NET Software verlangsamen würden.

Ein weiterer Faktor ist, dass JIT-Compiler nicht zu viel Zeit erweiterte Optimierungen zu tun leisten können, weil es zur Laufzeit ausgeführt wird, und der Endverbraucher würde es merken, wenn es zu viel Zeit in Anspruch nimmt. Auf der anderen Seite, ein C ++ Compiler hat die ganze Zeit es Optimierungen bei der Kompilierung tun muss. Dieser Faktor ist viel weniger wichtig als Speicherverbrauch, IMHO.

Ein besonderes Szenario, in dem C ++ noch die Oberhand hat (und wird für die kommenden Jahre) tritt auf, wenn polymorphe Entscheidungen bei der Kompilierung vorgegeben werden kann.

Im Allgemeinen Verkapselung und latente Entscheidungsfindung ist eine gute Sache, weil es den Code dynamisch macht, leichter an sich ändernde Anforderungen und leichter anpassbar als Rahmen zu verwenden. Aus diesem Grunde ist die objektorientierte Programmierung in C # sehr produktiv ist, und es kann unter dem Begriff „Verallgemeinerung“ verallgemeinert werden. Leider kommt diese besondere Art der Verallgemeinerung zu einem Preis zur Laufzeit.

In der Regel sind diese Kosten nicht wesentliche, aber es gibt Anwendungen, bei denen der Aufwand für virtuelle Methodenaufrufe und Objekterstellung einen Unterschied machen kann (vor allem, da virtuelle Methoden andere Optimierungen verhindern wie Methodenaufruf Inlining). Dies ist, wo C ++ einen großen Vorteil hat, weil Sie Vorlagen verwenden, eine andere Art von Generalisierung zu erreichen, die hat keine Auswirkungen auf die Laufzeit aber ist nicht unbedingt weniger polymorph als OOP. In der Tat, alle Mechanismen, die OOP darstellen kann nur Template-Techniken und Compiler-Auflösung modelliert werden.

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

C ++ (oder C was das betrifft) gibt Ihnen eine fein abgestimmte Kontrolle über Ihre Datenstrukturen. Wenn Sie wollen Bit-twiddle Sie diese Option haben. Große verwaltete Java oder .NET-Anwendungen (OWB, Visual Studio 2005 ), die die internen Daten verwenden Strukturen der Java / .NET-Bibliotheken tragen das Gepäck mit ihnen. Ich habe OWB Designer Sessions gesehen mit mehr als 400 MB RAM und BIDS für Würfel oder ETL Design als auch in die 100 von MB zu bekommen.

Auf einer vorhersagbaren Arbeitsbelastung (wie die meisten Benchmarks, die ein Prozess viele Male wiederholen) ein JIT können Sie Code, der gut genug ist optimiert, dass es keinen praktischen Unterschied ist.

IMO auf große Anwendungen ist der Unterschied nicht so sehr die JIT wie die Datenstrukturen, die der Code selbst verwendet. Wird ein Antrag Speicherlastig ist, werden Sie weniger effizient Cache-Nutzung erhalten. Cache-Misses auf modernen CPUs sind recht teuer. Wo C oder C ++ wirklich gewinnen ist, wo Sie Ihre Nutzung von Datenstrukturen optimieren können gut mit der CPU-Cache zu spielen.

Für Grafiken des Standard C # Graphics-Klasse ist viel langsamer als GDI über C / C ++ zugegriffen. Ich weiß, das hat nichts mit der Sprache an mich mehr mit der gesamten .NET-Plattform zu tun, aber Grafik ist das, was in den Entwickler als GDI Ersatz angeboten wird, und seine Leistung ist so schlecht, dass ich nicht einmal wagen, Grafiken zu tun mit ihm.

Wir haben eine einfache Benchmark wir nachschauen, wie schnell eine Grafik-Bibliothek ist, und das ist einfach zeichnen zufällige Linien in einem Fenster. C ++ / GDI ist immer noch bissig mit 10000 Zeilen, während C # / Graphics Schwierigkeiten hat 1000 in Echtzeit zu tun.

Die Garbage-Collection ist der Hauptgrund Java # KANN NICHT für Echtzeitsysteme verwendet werden.

  1. Wann wird die GC passieren?

  2. Wie lange wird es dauern?

Dies ist nicht deterministisch.

Wir haben zu bestimmen haben, wenn C # vergleichbar mit C ++ in der Leistung war und ich schrieb, dass einige Testprogramme (Visual Studio 2005 für beiden Sprachen verwenden). Es stellte sich heraus, dass ohne Müllabfuhr und unter Berücksichtigung nur die Sprache (nicht der Rahmen) C # im Grunde die gleiche Leistung wie C ++ hat. Die Speicherzuordnung ist viel schneller in C # als in C ++ und C # hat einen leichten Vorsprung in Determinismus, wenn Datengrößen jenseits Cache-Zeilengrenzen erhöht werden. all dies musste jedoch schließlich bezahlt werden und es gibt eine enorme Kosten in Form von nicht-deterministische Leistung für C # trifft aufgrund der Garbage Collection.

Wie üblich, es hängt von der Anwendung ab. Es gibt Fälle, in denen C # wahrscheinlich vernachlässigbar langsamen und anderen Fällen, in denen C ++ 5 oder 10-mal schneller, vor allem in Fällen, in denen Operationen können leicht SIMD'd werden.

Ich weiß, es ist nicht das, was Sie wurden gefragt, aber C # ist oft schneller schreiben als C ++, das ist ein großer Bonus in einem kommerziellen Umfeld ist.

C / C ++ kann erheblich besser in Programmen durchführen, wo es entweder großer Arrays oder schweres Looping / Iteration über Arrays (jede Größe) ist. Dies ist der Grund, die Grafiken sind in der Regel viel schneller in C / C ++, weil schwere Array-Operationen fast alle Grafikoperationen zugrunde liegen. .NET ist notorisch langsam in Array-Indizierung Operationen aufgrund aller Sicherheitskontrollen, und dies gilt insbesondere für die mehrdimensionale Arrays (und, ja, rechteckigen C # Arrays sind noch langsamer als gezackte C # Arrays).

Die Boni von C / C ++ am stärksten ausgeprägt sind, wenn Sie direkt mit Zeigern halten und vermeiden Boost, std::vector und anderen High-Level-Container, sowie inline jede kleine Funktion möglich. Verwenden Sie die alte Schule-Arrays, wann immer möglich. Ja, Sie werden mehr Zeilen Code müssen die gleiche Sache, die Sie haben in Java oder C # zu erreichen, wie Sie High-Level-Behälter vermeiden. Wenn Sie einen dynamisch angepassten Array benötigen, müssen Sie nur daran zu erinnern, Ihren new T[] mit einem entsprechenden delete[] Anweisung (oder Verwendung std::unique_ptr) -Der Preis für die zusätzliche Geschwindigkeit zu paaren ist, dass Sie mehr sorgfältig Code muss. Aber im Gegenzug erhalten Sie sich von den Overhead von verwalteten Speicher / Garbage Collector zu befreien, die sich leicht von 20% oder mehr betragen kann der Ausführungszeit stark objektorientierte Programme in Java und .NET, sowie diejenigen, massiven verwaltet Speicherfeld Indexierungskosten. C ++ Anwendungen können auch von einigen geschickten Compiler-Schalter in bestimmten Fällen profitieren.

Ich bin ein Experte Programmierer in C, C ++, Java und C #. Vor kurzem hatte ich die seltene Gelegenheit, die genau die gleiche algorithmische Programm in den letzten drei Sprachen zu implementieren. Das Programm hatte eine Menge Mathematik und mehrdimensionale Array-Operationen. Ich diese stark in allen drei Sprachen optimiert. Die Ergebnisse waren typisch für was normalerweise sehe ich in weniger strenge Vergleiche: Java war etwa 1,3x schneller als C # (die meisten JVMs mehr optimiert werden als die CLR) und der C ++ Rohzeiger Version kam in etwa 2,1x schneller als C # . Beachten Sie, dass das C # -Programm verwendet nur sichere Code-es ist meiner Meinung nach, dass Sie auch in C-Code könnte ++ vor dem unsafe Schlüsselwort.

Aus Furcht, dass jemand denke ich, etwas gegen C #, werde ich schließen, indem er sagte, dass C # wahrscheinlich Sprache ist mein Favorit. Es ist die logische, intuitive und schnelle Entwicklung Sprache, die ich bisher erlebt habe. Ich mache alle meine Prototyping in C #. Die Sprache C # hat viele kleine, subtile Vorteile gegenüber Java (ja, ich weiß, Microsoft die Chance hatte, viele von Java die Mängel zu beheben, indem Sie das Spiel spät eintritt und wohl das Kopieren von Java). Toast auf Java Calendar Klasse anyone? Wenn Microsoft jemals wirkliche Anstrengung verbringt die CLR und den .NET-Jitters zu optimieren, konnte C # ernsthaft zu übernehmen. Ich bin überrascht, ehrlich haben sie nicht bereits sie direkt in der Sprache C # so viele Dinge getan haben, warum es nicht Follow-up mit schwerer knall Compiler-Optimierungen? Vielleicht, wenn wir alle beg.

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

Ihre Schwierigkeit scheint, ob bei der Entscheidung zu sein, was Sie gehört haben, ist glaubwürdig, und diese Schwierigkeit wird nur wiederholt werden, wenn Sie versuchen, die Antworten auf dieser Seite zu bewerten.

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

Eine Möglichkeit für Beweise zu stellen wäre.

Wenn jemand behauptet, „es gibt einige Bereiche, in denen C # als C schneller sein beweist ++“ fragen sie Warum sie sagen, dass , sie bitten, Ihnen Messungen zu zeigen, fragen sie Ihnen Programme zeigen. Manchmal werden sie einfach einen Fehler gemacht haben. Manchmal werden Sie feststellen, dass sie nur eine Meinung zum Ausdruck, anstatt zu teilen etwas, das sie nachweisen können, um wahr zu sein.

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

  • "Nehmen Sie die Benchmarks unter http://shootout.alioth.debian.org / mit viel Skepsis, wie Dieser Test weitgehend arithmetischen Code, die höchstwahrscheinlich nicht ähnlich ist Ihr Code überhaupt nicht. "

    Fragen Sie sich, wenn Sie wirklich verstehen, was "diese weitgehend Test arithmetischer Code " Mittel, und dann fragen Sie sich, wenn der Autor hat gezeigt Sie tatsächlich, dass sein Anspruch ist wahr.

  • "Das ist ein ziemlich nutzlos Test, da es hängt wirklich davon ab, wie gut die einzelnen Programme wurden optimiert; Ich habe zu beschleunigen verwaltet einige von ihnen von 4-6 mal oder mehr, machen deutlich, dass der Vergleich zwischen nicht optimierten Programmen eher albern. "

    Fragen Sie sich, ob der Autor hat gezeigt Sie eigentlich, dass er es geschafft hat zu „beschleunigen, indem 4-6 einige von ihnen nach oben mal oder mehr!“- es ist ein einfacher Anspruch geltend zu machen

.NET-Sprachen können so schnell wie C ++ Code, oder sogar schneller, aber C ++ Code wird einen konstanten Durchsatz hat wie die .NET-Laufzeit für GC , auch wenn es um seine Pausen sehr klug ist.

Wenn Sie also einen Code haben, der konstant schnell hat zu laufen, ohne Pause, wird .NET vorstellen Latenz an einem gewissen Punkt , auch wenn Sie sehr vorsichtig mit dem Runtime-GC.

Für 'embarassingly parallel Probleme bei der Verwendung von Intel TBB und OpenMP auf C ++ Ich habe eine etwa 10-fach Leistungssteigerung im Vergleich zu ähnlichen (reiner Mathematik) Problemen gemacht mit C # und TPL beobachtet. SIMD ist ein Bereich, in der C # nicht konkurrieren können, aber ich habe auch den Eindruck, dass TPL einen beträchtlichen Overhead hat.

Das heißt, ich verwenden nur C ++ für leistungskritische Aufgaben, bei denen ich weiß, ich in der Lage sein wird, Multithreading und Ergebnisse schnell. Für alles andere, C # (und gelegentlich F #) ist gut so.

Es ist eine sehr vage Frage ohne wirkliche definitive Antworten.

Zum Beispiel; Ich würde eher 3D-Spiele spielen, die in C ++ erstellt werden, als in C #, weil die Leistung sicherlich viel besser ist. (Und ich weiß, XNA, etc., aber es kommt keine Möglichkeit, in der Nähe der Realität).

Auf der anderen Seite, wie bereits erwähnt; Sie sollten in einer Sprache entwickeln, mit dem Sie tun, was Sie wollen schnell, und dann bei Bedarf optimieren.

In der Theorie für lange laufende Server-Typ-Anwendung, eine JIT-kompilierten Sprache kann sich viel schneller als ein nativ kompiliert Pendant. Da die JIT kompilierten Sprache im Allgemeinen zunächst auf einem relativ niedrigen Niveau Zwischensprache kompiliert wird, können Sie auf jeden Fall eine Menge von der High-Level-Optimierungen direkt bei der Kompilierung tun. Der große Vorteil kommt, dass der JIT weiter im Fluge Codeabschnitt neu kompiliert werden, da es mehr und mehr Daten über bekommt, wie die Anwendung verwendet wird. Es kann die am häufigsten verwendeten Code-Pfade ordnet Verzweigungsvorhersage zu ermöglichen, so oft wie möglich erfolgreich zu sein. Es können separate Codeblöcke neu ordnen, die oft zusammen genannt werden, sie beide im Cache zu halten. Es kann mehr Mühe aufwenden innere Schleifen zu optimieren.

Ich bezweifle, dass dies durch .NET oder einen des JREs getan wird, aber es wurde untersucht, als ich in der Universität war, so ist es nicht unvernünftig zu glauben, dass diese Art von Dingen, ihren Weg in die realen Welt finden kann bei Irgendwann bald.

Anwendungen, die intensiven Speicherzugriff zB erfordern. Bildmanipulation ist in der Regel besser geschrieben in nicht verwalteten Umgebung (C ++) als verwaltete (C #). Optimiertes innere Schleifen mit Zeigern arithmetics sind viel einfache Kontrolle haben von in C ++. In C # müssen Sie möglicherweise unsicheren Code greifen auch in der Nähe der gleichen Leistung zu erhalten.

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

Ich bin mit Visual C # / C ++ 2010 Express-Editionen. Beide Projekte sind einfache Konsolenanwendungen, ich habe sie in Standard getestet (keine benutzerdefinierten Einstellungen) Release und Debug-Modus. C # Listen schneller laufen auf meinem PC, Feldinitialisierung ist auch schneller in C #, mathematischen Operationen sind langsamer.

Ich bin mit Intel Core2Duo P8600@2.4GHz, C # -. NET 4.0

Ich weiß, dass Vektor-Implementierung ist anders als C # Liste, aber ich wollte nur Sammlungen testen, die ich verwenden würde meine Objekte zu speichern (und Index-Accessor verwenden zu können).

Natürlich können Sie Speicher löschen müssen (sie für jeden Einsatz von new sagen), aber ich wollte den Code einfach halten.

C ++ Vektor Test :

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 # Liste Test:

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 Array füllen,
  • 1 s / 13sec Vektor init & füllen.

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

C #:

  • 20/20 ms Array init
  • 403/440 ms Array füllen,
  • 710/742 ms Liste init & füllen.

Nun, es hängt davon ab. Wenn der Byte-Code übersetzt in Maschinencode (und nicht nur JIT) (ich meine, wenn Sie das Programm ausführen) und , wenn Ihr Programm viele Zuteilungen / Aufheben dieser Zuordnungen verwendet, könnte es sein, schneller, weil die GC Algorithmus braucht nur einen durch~~POS=TRUNC (theoretisch) durch den gesamten Speicher nur einmal, sondern normale malloc / realloc / frei C / C ++ bei jedem Aufruf eine Overhead-Anrufe bewirkt (Call-Overhead, Datenstruktur-Overhead, Cache-Misses;).)

So ist es theoretisch möglich ist (auch für andere GC Sprachen).

Ich sehe nicht wirklich den extremen Nachteil nicht in der Lage sein, verwenden metaprogramming mit C # für die meisten Anwendungen, da die meisten Programmierer tun es sowieso nicht verwendet werden.

Ein weiterer großer Vorteil ist, dass die SQL, wie die LINQ "Erweiterung", Möglichkeiten bietet für die Compiler-Anrufe auf Datenbanken zu optimieren (in anderen Worten, der Compiler könnte die ganze LINQ to one „Blob“ binary kompilieren, wo die aufgerufenen Funktionen inlined sind oder für die Nutzung optimiert, aber ich bin zu spekulieren hier).

Ich nehme an, es gibt Anwendungen in C # geschrieben schnell ausgeführt wird, sowie mehr C ++ geschrieben Anwendungen schnell laufen (auch C ++ nur älter ... und UNIX nehmen auch ...)
- die Frage ist in der Tat - was ist das, was die Benutzer und Entwickler klagen über ...
Nun, meiner Meinung nach, im Falle von C # haben wir sehr Komfort UI, sehr schöne Hierarchie der Bibliotheken und ganze Schnittstellensystem von CLI. Im Fall von C ++ haben wir Vorlagen, ATL, COM, MFC und ganzer Kram von alreadyc geschrieben und Ausführen von Code wie OpenGL, DirectX und so weiter ... Entwickler klagen über unbestimmbar gestiegen GC ruft bei C # (bedeutet Programm schnell läuft, und in einer Sekunde - Knall es steckt)
!. Zum Schreiben von Code in C # sehr einfach und schnell (nicht zu vergessen, dass auch Fehlerrisiko erhöhen. Im Fall von C ++, klagen Entwickler von Speicherlecks, - bedeuten, zermalmt, Anrufe zwischen DLLs, sowie von „DLL Hell“ - Problem mit Unterstützung und Ersatz Bibliotheken durch neuere ...
Ich denke, mehr Können Sie in der Programmiersprache haben werden, die mehr Qualität (und Geschwindigkeit) wird die Software charakterisieren.

Ich würde es so sagen: Programmierer, die schneller Code schreiben, sind diejenigen, die die mehr informiert sind, was aktuelle Maschinen macht schnell gehen, und nebenbei sind sie auch diejenigen, die ein geeignetes Werkzeug verwenden, die für eine präzise Low- erlaubt Ebene und deterministische Optimierungstechniken. Aus diesen Gründen sind diese Menschen diejenigen, die C verwenden / C ++ statt C #. Ich würde so weit wie die besagt, dies als Tatsache gehen.

> Immerhin haben die Antworten irgendwo sein, nicht wahr? :)

Ähm, nein.

Wie mehr Antworten erwähnt, ist die Frage unter angegebener in einer Weise, die Fragen in Reaktion einladen, keine Antworten. Um nur einen Weg:

Und dann die Programme? Welche Maschine? Welches OS? Welche Datenmenge?

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

Und wenn Sie nehmen in allen anderen Kompilierung-Optimierungen durch so viele andere erwähnt, sowie der Mangel an Sicherheit, das tut, ja, mehr Geschwindigkeit bedeuten ...

Ich würde sagen, C ++ die offensichtliche Wahl ist im Hinblick auf die rohe Geschwindigkeit und minimalen Speicherverbrauch. Aber das führt auch zu mehr Zeit, um den Code zu entwickeln und sicherzustellen, dass Sie nicht Speicher undicht sind oder dass irgendwelche Null-Zeiger-Ausnahmen.

Urteil:

  • C #: Schnellere Entwicklung, langsamer Lauf

  • C ++: Langsame Entwicklung, schneller Lauf

  • .

Es hängt wirklich davon ab, was Sie versuchen in Ihrem Code zu erreichen. Ich habe gehört, dass es nur Sachen urbaner Legende ist, dass es zwischen VB.NET, C # jeder Unterschied in der Leistung ist und verwaltet C ++. Allerdings habe ich zumindest in Stringvergleichen gefunden, dass C ++ verwaltet die Hosen weg von C # schlägt, was wiederum die Hosen weg von VB.NET schlägt.

Ich habe keineswegs irgendwelche erschöpfenden Vergleiche in algorithmischer Komplexität zwischen den Sprachen erfolgen. Ich verwende auch nur die Standardeinstellung in jedem der Sprache. In VB.NET Ich bin mit Einstellungen Deklaration von Variablen zu verlangen, usw. Hier ist der Code ich für verwaltete C ++: (Wie Sie sehen können, ist dieser Code ganz einfach). Ich bin die gleiche in den anderen Sprachen in Visual Studio 2013 mit .NET 4.6.2 ausgeführt wird.

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

Hinsichtlich der Leistung gibt es einige wesentliche Unterschiede zwischen C# und C++:

  • C# basiert auf GC/Heap.Die Zuweisung und GC selbst sind Overhead, da der Speicherzugriff nicht lokal erfolgt
  • C++-Optimierer sind im Laufe der Jahre sehr gut geworden.JIT-Compiler können nicht das gleiche 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 Wert als Argument übergeben wurden.Sie können es in C++ tatsächlich noch schlimmer machen, wenn Sie nicht aufpassen.

durch diese inspiriert, habe ich einen schnellen Test mit 60 Prozent des gemeinsamen Unterricht benötigt in den meisten der Programme.

Hier ist der C # -Code:

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

String-Array und Arraylist verwendet werden, diese Anweisungen absichtlich aufzunehmen.

Hier ist der c ++ Code:

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

Die Eingabedateigröße I verwendet wurde, war 40 KB.

Und hier ist das Ergebnis -

  • C ++ Code lief in 9 Sekunden.
  • C # -Code: 4 Sekunden !!!

Oh, aber das war auf Linux ... Mit C # läuft auf Mono ... und C ++ mit g ++.

OK, das ist das, was ich unter Windows bekam - Visual Studio 2003 :

  • C # -Code lief in 9 Sekunden.
  • C ++ Code - schrecklich 370 Sekunden !!!
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top