Domanda

O ora è il contrario?

Da quello che ho sentito ci sono alcune aree in cui C # si rivela più veloce di C ++, ma non ho mai avuto il coraggio di provarlo da solo.

Pensavo che qualcuno di voi potesse spiegare queste differenze in dettaglio o indicarmi il posto giusto per informazioni al riguardo.

È stato utile?

Soluzione

Non vi è alcun motivo rigoroso per cui un linguaggio basato su bytecode come C # o Java che abbia un JIT non può essere veloce come il codice C ++. Tuttavia il codice C ++ era significativamente più veloce per molto tempo, e anche oggi lo è ancora in molti casi. Ciò è dovuto principalmente al fatto che le ottimizzazioni JIT più avanzate sono complicate da implementare e quelle davvero interessanti stanno arrivando solo ora.

Quindi il C ++ è più veloce, in molti casi. Ma questa è solo una parte della risposta. I casi in cui C ++ è effettivamente più veloce, sono programmi altamente ottimizzati, in cui programmatori esperti hanno ottimizzato a fondo il codice. Ciò non solo richiede molto tempo (e quindi è costoso), ma spesso porta anche a errori dovuti a ottimizzazioni eccessive.

D'altra parte, il codice nei linguaggi interpretati diventa più veloce nelle versioni successive del runtime (.NET CLR o Java VM), senza che tu faccia nulla. E ci sono molte utili ottimizzazioni che i compilatori JIT possono fare che sono semplicemente impossibili in linguaggi con puntatori. Inoltre, alcuni sostengono che la garbage collection dovrebbe essere generalmente veloce o più veloce della gestione manuale della memoria, e in molti casi lo è. In genere puoi implementare e ottenere tutto ciò in C ++ o C, ma sarà molto più complicato e soggetto a errori.

Come diceva Donald Knuth, "l'ottimizzazione prematura è la radice di tutto il male". Se sai davvero per certo che la tua applicazione consisterà per lo più in aritmetica critica per le prestazioni, e che sarà il collo di bottiglia, e sicuramente sarà più veloce in C ++, e sei sicuro che C ++ non entrerà in conflitto con l'altra requisiti, scegli C ++. In ogni altro caso, concentrati prima sull'implementazione corretta della tua applicazione in qualsiasi linguaggio tu preferisca, poi trova i colli di bottiglia delle prestazioni se funziona troppo lentamente e poi pensa a come ottimizzare il codice. Nel peggiore dei casi, potresti dover chiamare il codice C attraverso un'interfaccia di funzione esterna, quindi avrai comunque la possibilità di scrivere parti critiche in un linguaggio di livello inferiore.

Tieni presente che è relativamente facile ottimizzare un programma corretto, ma molto più difficile correggere un programma ottimizzato.

Dare percentuali effettive di vantaggi di velocità è impossibile, dipende in gran parte dal codice. In molti casi, l'implementazione del linguaggio di programmazione non è nemmeno il collo di bottiglia. Prendi i parametri di riferimento su http://benchmarksgame.alioth.debian.org/ con grande scetticismo , poiché questi test ampiamente testano il codice aritmetico, che molto probabilmente non è affatto simile al tuo codice.

Altri suggerimenti

C # potrebbe non essere più veloce, ma ti rende più veloce. Questa è la misura più importante per quello che faccio. :)

È più veloce di cinque arance. O meglio: non ci può essere una risposta (corretta) coperta. C ++ è un linguaggio compilato staticamente (ma poi c'è anche l'ottimizzazione guidata dal profilo), C # viene aiutato da un compilatore JIT. Ci sono così tante differenze che domande come & # 8220; quanto più veloce & # 8221; non si può rispondere nemmeno dando ordini di grandezza.

Inizierò in disaccordo con una parte della risposta accettata (e ben votata) a questa domanda affermando:

In realtà ci sono molte ragioni per cui il codice JITted verrà eseguito più lentamente di un C ++ correttamente ottimizzato (o di un'altra lingua senza sovraccarico del runtime) programma incluso:

  • i cicli di calcolo spesi sul codice JITting in fase di esecuzione non sono per definizione disponibili per l'uso nell'esecuzione del programma.

  • qualsiasi percorso attivo in JITter sarà in competizione con il tuo codice per istruzioni e cache di dati nella CPU. Sappiamo che la cache domina quando si tratta di prestazioni e che i linguaggi nativi come C ++ non hanno questo tipo di contesa, per definizione.

  • il budget temporale di un ottimizzatore di runtime è necessariamente molto più limitato di quello di un ottimizzatore di tempo di compilazione (come sottolineato da un altro commentatore)

In conclusione: alla fine, sarai quasi certamente in grado di creare un'implementazione più veloce in C ++ di quanto tu possa fare in C # .

Ora, detto ciò, quanto più velocemente non è davvero quantificabile, poiché ci sono troppe variabili: l'attività, il dominio del problema, l'hardware, la qualità delle implementazioni e molti altri fattori. Avrai eseguito test sul tuo scenario per determinare la differenza di prestazioni e poi decidere se valga la pena lo sforzo e la complessità aggiuntivi.

Questo è un argomento molto lungo e complesso, ma penso che valga la pena menzionare per completezza che l'ottimizzatore di runtime di C # è eccellente ed è in grado di eseguire determinate ottimizzazioni dinamiche in fase di runtime che non sono semplicemente disponibili per C ++ con la sua compilazione -tempo (statico) ottimizzatore. Anche con questo, il vantaggio è ancora in genere profondamente nella corte dell'applicazione nativa, ma l'ottimizzatore dinamico è la ragione per " quasi certamente " qualificatore indicato sopra.

-

In termini di prestazioni relative, sono stato anche disturbato dalle cifre e dalle discussioni che ho visto in alcune altre risposte, quindi ho pensato di intervenire e allo stesso tempo fornire supporto alle dichiarazioni che ho fatto sopra .

Una grande parte del problema con questi benchmark è che non puoi scrivere codice C ++ come se stessi scrivendo C # e ti aspetti di ottenere risultati rappresentativi (es. eseguire migliaia di allocazioni di memoria in C ++ ti darà numeri terribili. )

Invece, ho scritto un codice C ++ leggermente più idiomatico e confrontato con il codice C # fornito da @Wiory. Le due principali modifiche che ho apportato al codice C ++ sono state:

1) vettore utilizzato :: reserve ()

2) ha appiattito l'array 2d a 1d per ottenere una migliore localizzazione della cache (blocco contiguo)

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

Tempo di esecuzione (versione): Init: 124 ms, riempimento: 165 ms

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

Tempo di esecuzione (versione): Init: 398 's (sì, sono microsecondi), Fill: 152ms

Tempo totale di esecuzione: C #: 289 ms, C ++ 152 ms (circa il 90% più veloce)

Osservazioni

  • Modifica dell'implementazione C # nella stessa implementazione di array 1d ha prodotto Init: 40ms, Fill: 171ms, Total: 211ms ( C ++ era ancora quasi 40% più veloce ).

  • È molto più difficile progettare e scrivere "velocemente" codice in C ++ rispetto alla scrittura di "normale" codice in entrambe le lingue.

  • È (forse) sorprendentemente facile ottenere scarse prestazioni in C ++; lo abbiamo visto con prestazioni di vettori senza prenotazione. E ci sono molte insidie ??come questa.

  • Le prestazioni di C # sono piuttosto sorprendenti se si considera tutto ciò che sta accadendo in fase di esecuzione. E quella performance è relativamente facile l'accesso.

  • Ulteriori dati aneddotici che confrontano le prestazioni di C ++ e C #: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore

La linea di fondo è che C ++ ti dà molto più controllo sulle prestazioni. Vuoi usare un puntatore? Un riferimento? Stack memoria? Mucchio? Polimorfismo dinamico o eliminare l'overhead di runtime di una tabella con polimorfismo statico (tramite modelli / CRTP)? In C ++ devi ... er, arrivare a fare tutte queste scelte (e altro) te stesso, idealmente in modo che la tua soluzione affronti al meglio il problema che stai affrontando.

Chiediti se effettivamente vuoi o hai bisogno di quel controllo, perché anche per l'esempio banale sopra, puoi vedere che sebbene ci sia un significativo miglioramento delle prestazioni, per accedere richiede un investimento più profondo.

Nella mia esperienza (e ho lavorato molto con entrambe le lingue), il problema principale con C # rispetto a C ++ è il consumo elevato di memoria e non ho trovato un buon modo per controllarlo. Era il consumo di memoria che alla fine avrebbe rallentato il software .NET.

Un altro fattore è che il compilatore JIT non può permettersi troppo tempo per eseguire ottimizzazioni avanzate, poiché viene eseguito in fase di esecuzione e l'utente finale lo noterà se impiega troppo tempo. D'altra parte, un compilatore C ++ ha tutto il tempo necessario per eseguire ottimizzazioni in fase di compilazione. Questo fattore è molto meno significativo del consumo di memoria, IMHO.

Uno scenario particolare in cui il C ++ ha ancora il sopravvento (e lo sarà, per gli anni a venire) si verifica quando le decisioni polimorfiche possono essere predeterminate al momento della compilazione.

Generalmente, l'incapsulamento e il processo decisionale differito sono una buona cosa perché rendono il codice più dinamico, più facile da adattare ai mutevoli requisiti e più facile da usare come framework. Questo è il motivo per cui la programmazione orientata agli oggetti in C # è molto produttiva e può essere generalizzata con il termine & # 8220; generalizzazione & # 8221 ;. Sfortunatamente, questo particolare tipo di generalizzazione ha un costo in fase di esecuzione.

Di solito, questo costo non è sostanziale, ma ci sono applicazioni in cui l'overhead delle chiamate al metodo virtuale e la creazione di oggetti possono fare la differenza (soprattutto perché i metodi virtuali impediscono altre ottimizzazioni come l'inserimento di chiamate di metodo). Questo è dove C ++ ha un enorme vantaggio perché puoi usare i template per ottenere un diverso tipo di generalizzazione che ha nessun impatto sul runtime ma non è necessariamente meno polimorfico di OOP. In effetti, tutti i meccanismi che costituiscono OOP possono essere modellati usando solo tecniche di template e risoluzione in fase di compilazione.

In questi casi (e, certamente, sono spesso limitati a domini con problemi speciali), C ++ vince contro C # e linguaggi comparabili.

C ++ (o C del resto) ti offre un controllo approfondito sulle tue strutture di dati. Se vuoi fare il bit-twiddle hai questa opzione. Grandi app Java o .NET gestite (OWB, Visual & nbsp; Studio & nbsp; 2005 ) che utilizzano il le strutture dati interne delle librerie Java / .NET portano con sé il bagaglio. Ho visto sessioni di progettazione OWB utilizzando oltre 400 MB di RAM e BIDS per cubo o ETL design che arriva anche ai 100 di MB.

Su un carico di lavoro prevedibile (come la maggior parte dei benchmark che ripetono un processo più volte), un JIT può ottenere un codice ottimizzato abbastanza bene da non avere differenze pratiche.

IMO su applicazioni di grandi dimensioni la differenza non è tanto nella JIT quanto nelle strutture di dati utilizzate dal codice stesso. Laddove un'applicazione è ricca di memoria, si otterrà un utilizzo della cache meno efficiente. I cache mancati nelle CPU moderne sono piuttosto costosi. Dove C o C ++ vincono davvero è dove puoi ottimizzare l'utilizzo delle strutture dati per giocare bene con la cache della CPU.

Per la grafica, la classe grafica standard C # è molto più lenta di GDI a cui si accede tramite C / C ++. So che questo non ha nulla a che fare con il linguaggio in sé, più con la piattaforma .NET totale, ma la grafica è ciò che viene offerto allo sviluppatore in sostituzione di GDI e le sue prestazioni sono così pessime che non oserei nemmeno fare la grafica con esso.

Abbiamo un semplice benchmark che usiamo per vedere quanto è veloce una libreria grafica e che è semplicemente disegnare linee casuali in una finestra. C ++ / GDI è ancora veloce con 10000 linee mentre C # / Graphics ha difficoltà a fare 1000 in tempo reale.

La garbage collection è il motivo principale per cui Java # NON PU be essere utilizzato per i sistemi in tempo reale.

  1. Quando avverrà il CG?

  2. Quanto tempo ci vorrà?

Questo non è deterministico.

Abbiamo dovuto determinare se C # era paragonabile a C ++ nelle prestazioni e per questo ho scritto alcuni programmi di test (usando Visual Studio 2005 per entrambi i linguaggi). Si è scoperto che senza garbage collection e considerando solo il linguaggio (non il framework) C # ha sostanzialmente le stesse prestazioni del C ++. L'allocazione della memoria è molto più veloce in C # che in C ++ e C # ha un leggero vantaggio nel determinismo quando le dimensioni dei dati vengono aumentate oltre i limiti delle linee della cache. Tuttavia, tutto questo alla fine ha dovuto essere pagato e c'è un costo enorme sotto forma di hit non deterministiche per C # a causa della garbage collection.

Come al solito, dipende dall'applicazione. Ci sono casi in cui C # è probabilmente trascurabilmente più lento, e altri casi in cui C ++ è 5 o 10 volte più veloce, specialmente nei casi in cui le operazioni possono essere facilmente SIMD.

So che non è quello che stavi chiedendo, ma C # è spesso più veloce scrivere rispetto a C ++, che è un grande vantaggio in un contesto commerciale.

C / C ++ può funzionare molto meglio nei programmi in cui sono presenti array di grandi dimensioni o loop / iterazione su array pesanti (di qualsiasi dimensione). Questo è il motivo per cui la grafica è generalmente molto più veloce in C / C ++, poiché le operazioni di array pesanti sono alla base di quasi tutte le operazioni di grafica. .NET è notoriamente lento nelle operazioni di indicizzazione degli array a causa di tutti i controlli di sicurezza, e questo è particolarmente vero per gli array multidimensionali (e, sì, gli array C # rettangolari sono persino più lenti degli array C # frastagliati).

I bonus di C / C ++ sono più pronunciati se rimani direttamente con i puntatori ed eviti Boost, std :: vector e altri contenitori di alto livello, nonché inline ogni piccola funzione possibile. Utilizzare array di vecchia scuola ogni volta che è possibile. Sì, avrai bisogno di più righe di codice per realizzare la stessa cosa che hai fatto in Java o C # evitando i container di alto livello. Se hai bisogno di un array di dimensioni dinamiche, dovrai solo ricordare di accoppiare il tuo nuovo T [] con una corrispondente istruzione delete [] (o usare std: : unique_ptr ): il prezzo per la velocità extra è che devi codificare più attentamente. Ma in cambio, ti sbarazzerai del sovraccarico di memoria gestita / garbage collector, che può facilmente essere il 20% o più del tempo di esecuzione di programmi fortemente orientati agli oggetti in Java e .NET, nonché di quelli gestiti in modo massiccio costi di indicizzazione dell'array di memoria. Le app C ++ possono anche beneficiare di alcuni switch di compilazione eleganti in alcuni casi specifici.

Sono un programmatore esperto in C, C ++, Java e C #. Di recente ho avuto la rara occasione di implementare esattamente lo stesso programma algoritmico nelle ultime 3 lingue. Il programma aveva molte operazioni matematiche e di array multidimensionali. Ho fortemente ottimizzato questo in tutte e 3 le lingue. I risultati erano tipici di quello che normalmente vedo in confronti meno rigorosi: Java era circa 1,3 volte più veloce di C # (la maggior parte delle JVM sono più ottimizzate rispetto al CLR) e la versione del puntatore raw C ++ era di circa 2,1 volte più veloce di C # . Nota che il programma C # utilizzava solo un codice sicuro: è mia opinione che potresti anche codificarlo in C ++ prima di utilizzare la parola chiave non sicura .

Per timore che qualcuno pensi che io abbia qualcosa contro C #, chiuderò dicendo che C # è probabilmente la mia lingua preferita. È il linguaggio di sviluppo più logico, intuitivo e rapido che abbia mai incontrato finora. Faccio tutta la mia prototipazione in C #. Il linguaggio C # ha molti piccoli e sottili vantaggi rispetto a Java (sì, so che Microsoft ha avuto la possibilità di correggere molte delle carenze di Java entrando nel gioco in ritardo e probabilmente copiando Java). Brindare alla classe Calendar di Java qualcuno? Se Microsoft spendesse mai davvero sforzi per ottimizzare CLR e .NET JITter, C # potrebbe prendere seriamente il controllo. Sono sinceramente sorpreso che non lo abbiano già fatto: hanno fatto così tante cose nel linguaggio C #, perché non seguirlo con ottimizzazioni del compilatore di grande impatto? Forse se tutti preghiamo.

> Da quello che ho sentito ...

La tua difficoltà sembra essere nel decidere se ciò che hai ascoltato sia credibile e tale difficoltà si ripeterà solo quando proverai a valutare le risposte su questo sito.

Come deciderai se le cose che la gente dice qui sono più o meno credibili di quanto hai sentito in origine?

Un modo sarebbe chiedere prove .

Quando qualcuno afferma "ci sono alcune aree in cui C # si rivela più veloce di C ++" chiedi loro perché dicono che , chiedi loro di mostrarti le misure, chiedi loro di mostrarti i programmi. A volte avranno semplicemente fatto un errore. A volte scoprirai che stanno solo esprimendo un'opinione piuttosto che condividere qualcosa che possono mostrare come veri.

Spesso informazioni e opinioni saranno confuse in ciò che la gente afferma e dovrai cercare di capire quale è quale. Ad esempio, dalle risposte in questo forum:

  • " Prendi i benchmark su http: //shootout.alioth.debian. org / con molto scetticismo, come questi test ampiamente testano il codice aritmetico, che molto probabilmente non è simile a il tuo codice. "

    Chiediti se davvero capire cosa " questi test ampiamente codice aritmetico " , quindi chiediti se l'autore ha in realtà ti ha mostrato che la sua richiesta è vero.

  • " Questo è un test piuttosto inutile, dal momento che dipende davvero da quanto bene i singoli programmi sono stati ottimizzato; Sono riuscito ad accelerare alcuni di 4-6 volte o più, chiarendo che il confronto tra programmi non ottimizzati è piuttosto sciocco. "

    Chiediti se l'autore ha in realtà ti ha mostrato che è riuscito per "accelerare alcuni di essi di 4-6 volte o più " - è un'affermazione facile da fare!

I linguaggi .NET possono essere veloci come il codice C ++, o anche più veloci, ma il codice C ++ avrà un throughput più costante poiché il runtime .NET deve mettere in pausa per GC , anche se è molto intelligente sulle sue pause.

Quindi, se hai del codice che deve essere eseguito in modo coerente e veloce senza alcuna pausa, .NET introdurrà la latenza ad un certo punto , anche se stai molto attento con il GC di runtime.

Per problemi 'imbarazzantemente paralleli', usando Intel TBB e OpenMP su C ++ ho osservato un aumento delle prestazioni di circa 10 volte rispetto a problemi simili (matematica pura) fatti con C # e TPL. SIMD è un'area in cui C # non può competere, ma ho anche avuto l'impressione che TPL abbia un notevole sovraccarico.

Detto questo, utilizzo C ++ solo per attività critiche per le prestazioni in cui so che sarò in grado di eseguire il multithread e ottenere risultati rapidamente. Per tutto il resto, C # (e occasionalmente F #) va bene.

È una domanda estremamente vaga senza vere risposte definitive.

Ad esempio; Preferirei giocare a giochi 3D creati in C ++ piuttosto che in C #, perché le prestazioni sono sicuramente molto migliori. (E conosco XNA, ecc., Ma non si avvicina affatto alla cosa reale).

D'altra parte, come precedentemente menzionato; dovresti sviluppare in un linguaggio che ti consenta di fare ciò che desideri rapidamente e, se necessario, ottimizzare.

In teoria, per un'applicazione di tipo server di lunga durata, un linguaggio compilato JIT può diventare molto più veloce di una controparte compilata nativamente. Poiché il linguaggio compilato JIT viene generalmente compilato per la prima volta in un linguaggio intermedio di livello piuttosto basso, è comunque possibile eseguire molte ottimizzazioni di alto livello in fase di compilazione. Il grande vantaggio sta nel fatto che JIT può continuare a ricompilare sezioni di codice al volo man mano che ottiene sempre più dati su come viene utilizzata l'applicazione. Può organizzare i percorsi di codice più comuni per consentire il successo della previsione delle filiali il più spesso possibile. Può riorganizzare blocchi di codice separati che vengono spesso chiamati insieme per tenerli entrambi nella cache. Può spendere più sforzi per ottimizzare i circuiti interni.

Dubito che ciò sia stato fatto da .NET o da qualsiasi JRE, ma è stato oggetto di ricerche quando ero all'università, quindi non è irragionevole pensare che questo tipo di cose possano trovare la loro strada nel mondo reale a qualche punto presto.

Applicazioni che richiedono un accesso intensivo alla memoria, ad es. la manipolazione delle immagini è generalmente meglio scritta in ambiente non gestito (C ++) che gestita (C #). I loop interni ottimizzati con aritmetica del puntatore sono molto più facili da controllare in C ++. In C # potrebbe essere necessario ricorrere a codice non sicuro per avvicinarsi alle stesse prestazioni.

Ho testato vector in equivalente C ++ e C # - List e semplici array 2d.

Sto usando le versioni Visual C # / C ++ 2010 Express. Entrambi i progetti sono semplici applicazioni console, le ho testate in versione standard (senza impostazioni personalizzate) e modalità debug. Gli elenchi C # funzionano più velocemente sul mio PC, l'inizializzazione dell'array è anche più veloce in C #, le operazioni matematiche sono più lente.

Sto usando Intel Core2Duo P8600@2.4GHz, C # - .NET 4.0.

So che l'implementazione vettoriale è diversa dall'elenco C #, ma volevo solo testare raccolte che avrei usato per archiviare i miei oggetti (e potendo usare il programma di accesso all'indice).

Ovviamente devi cancellare la memoria (diciamo per ogni uso di new ), ma volevo mantenere il codice semplice.

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

Test elenco 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 ++ - 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);

}

Time: (Release / Debug)

C ++

  • 600/606 ms array array,
  • riempimento array 200/270 ms,
  • 1sec / 13sec vector init & amp; riempire.

(Sì, 13 secondi, ho sempre problemi con liste / vettori in modalità debug.)

C #:

  • 20/20 ms array array,
  • riempimento array 403/440 ms,
  • 710/742 ms elenco init & amp; riempire.

Beh, dipende. Se il codice byte viene tradotto in codice macchina (e non solo JIT) (intendo se esegui il programma) e se il tuo programma utilizza molte allocazioni / deallocazioni potrebbe essere più veloce perché il GC l'algoritmo richiede solo un passaggio (teoricamente) una volta sola, ma normale malloc / realloc / free Le chiamate C / C ++ causano un overhead su ogni chiamata (overhead di chiamata, overhead della struttura dei dati, mancate cache;)).

Quindi è teoricamente possibile (anche per altri linguaggi GC).

Non vedo davvero l'estremo svantaggio di non poter usare metaprogramming con C # per la maggior parte delle applicazioni, perché la maggior parte dei programmatori non lo utilizza comunque.

Un altro grande vantaggio è che SQL, come LINQ " extension " ;, fornisce opportunità per il compilatore di ottimizzare le chiamate ai database (in altre parole, il compilatore potrebbe compilare l'intero LINQ in un "binario" in cui le funzioni chiamate sono incorporate o per il tuo uso ottimizzato, ma sto speculando qui).

Suppongo che ci siano applicazioni scritte in C # in esecuzione veloce, così come ci sono più app scritte in C ++ in esecuzione veloce (bene C ++ solo più vecchio ... e prendere anche UNIX ...)
- la domanda è davvero - che cos'è quella cosa, utenti e sviluppatori si lamentano ...
Bene, IMHO, in caso di C # abbiamo un'interfaccia utente molto comoda, una bella gerarchia di librerie e l'intero sistema di interfaccia della CLI. Nel caso di C ++ abbiamo modelli, ATL, COM, MFC e un'intera serie di codici scritti ed in esecuzione alreadyc come OpenGL, DirectX e così via ... Gli sviluppatori si lamentano di chiamate GC indeterminatamente aumentate in caso di C # (significa che il programma funziona veloce e in un secondo - botto! è bloccato).
Scrivere codice in C # molto semplice e veloce (per non dimenticare che aumenta anche la possibilità di errori. Nel caso di C ++, gli sviluppatori lamentano perdite di memoria, - significa schiacciamenti, chiamate tra DLL, nonché "inferno DLL"; - problema con le librerie di supporto e sostituzione con quelle più recenti ...
Penso che più abilità avrai nel linguaggio di programmazione, più qualità (e velocità) caratterizzeranno il tuo software.

La metterei così: i programmatori che scrivono codice più veloce, sono quelli che sono più informati su ciò che rende veloci le macchine attuali, e per inciso sono anche quelli che usano uno strumento appropriato che consente di tecniche di ottimizzazione di livello e deterministiche. Per questi motivi, queste persone sono quelle che usano C / C ++ anziché C #. Andrei fino a dichiarare questo come un dato di fatto.

> Dopo tutto, le risposte devono essere da qualche parte, no? :)

Umm, no.

Come indicato da diverse risposte, la domanda è sotto specificata in modo da invitare domande in risposta, non risposte. Per prendere solo un modo:

E poi quali programmi? Quale macchina? Quale sistema operativo? Quale set di dati?

Se non sbaglio, i modelli C # sono determinati in fase di esecuzione. Questo deve essere più lento dei modelli di tempo di compilazione di C ++.

E quando prendi in considerazione tutte le altre ottimizzazioni in fase di compilazione menzionate da così tanti altri, così come la mancanza di sicurezza che, in effetti, significa più velocità ...

Direi che C ++ è la scelta ovvia in termini di velocità raw e consumo minimo di memoria. Ma ciò si traduce anche in più tempo nello sviluppo del codice e nell'assicurarsi che non si stia perdendo memoria o causando eccezioni al puntatore null.

Verdetto:

  • C #: sviluppo più rapido, corsa più lenta

  • C ++: sviluppo lento, corsa più veloce.

Dipende davvero da cosa stai cercando di realizzare nel tuo codice. Ho sentito che è solo roba da leggenda urbana che ci sia qualche differenza di prestazioni tra VB.NET, C # e C ++ gestito. Tuttavia, ho scoperto, almeno nei confronti di stringhe, che il C ++ gestito batte i pantaloni di C #, che a sua volta batte i pantaloni di VB.NET.

Non ho mai fatto alcun confronto esaustivo nella complessità algoritmica tra le lingue. Sto anche solo usando le impostazioni predefinite in ciascuna delle lingue. In VB.NET sto usando le impostazioni per richiedere la dichiarazione di variabili, ecc. Ecco il codice che sto usando per C ++ gestito: (Come puoi vedere, questo codice è abbastanza semplice). Sto eseguendo lo stesso nelle altre lingue in Visual Studio 2013 con .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;
}

Esistono alcune importanti differenze tra C # e C ++ sull'aspetto delle prestazioni:

  • C # è basato su GC / heap. L'allocazione e la stessa GC sono spese generali come non località dell'accesso alla memoria
  • Gli ottimizzatori C ++ sono diventati molto buoni nel corso degli anni. I compilatori JIT non possono raggiungere lo stesso livello poiché hanno solo un tempo di compilazione limitato e non vedono l'ambito globale

Oltre a ciò la competenza del programmatore gioca anche un ruolo. Ho visto un cattivo codice C ++ in cui le classi venivano passate per valore come argomento dappertutto. Puoi effettivamente peggiorare la situazione in C ++ se non presti attenzione.

Ispirato da questo, ho fatto un rapido test con il 60 percento delle istruzioni comuni necessarie nella maggior parte dei programmi.

Ecco & # 8217; s il codice 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();
}

L'array di stringhe e l'arraylist sono usati di proposito per includere quelle istruzioni.

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

La dimensione del file di input che ho usato era 40 & nbsp; KB.

Ed ecco il risultato -

  • Codice C ++ eseguito in 9 secondi.
  • codice C #: 4 secondi !!!

Oh, ma questo era su Linux ... Con C # in esecuzione su Mono ... E C ++ con g ++.

OK, questo è quello che ho ottenuto su Windows & # 8211; Visual & nbsp; Studio & nbsp; 2003 :

  • Il codice C # è stato eseguito in 9 secondi.
  • Codice C ++ & # 8211; orribili 370 secondi !!!
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top