C vs C++

Liittynyt
05.11.2017
Viestejä
102
Tulipa tuolla pelit - puolella puheeksi C vs C++. Joten päätin mitata käytännössä.

Käänsin flangin C ja C++ - kääntäjillä. g++:lla ei käänny ilman -permissive - lippua. Lisäksi tulee 1000 warningia. Tämä koska flang on C-ohjelma. C:llä ei varoituksia -pedantic -Wall. flang - koodi oli molemmissa täysin sama. g++:lla löysin itseasiassa muutaman bugin, joista gcc ei varoittanut ollenkaan.

Ajoin brutaalin euler_problems.flang 6-kertaa. Laitoin komennon millä käänsin flangin. Samat optimoinnit molemmissa. Se pistää tietokoneen polvilleen. Niinkuin pitääkin. flang/euler_problems.flang at master · mystikkogames/flang · GitHub
Otin netin pois ja kaikki muut ohjelmat, jotta testi olisi tasapuolinen.
C++:n RUN#4: Varmistaakseni muutin vielä .c-filut .c++:ksi, mutta oli ohjelmia jo auki. Mutta samoissa ajoissa.

Lopputuloksena: C:n paras aika: 151.239s ja C++:n 151.280s. Joten käytännössä samat ajat. Mutta C-ohjelmat kannattaa ajella C- ja C++-kääntäjillä bugien takia.

C++

RUN#1: g++ -O3 -fpermissive -Wall *.c -o flang
euler_1 # 0.003s
euler_2 # 0.000s
euler_3 # 0.154s
euler_4 # 0.032s
euler_5 # 0.005s
euler_6 # 0.000s
euler_7 # 2.769s
euler_8 # 0.038s
euler_9 # 0.891s
euler_10 # 113.614s
euler_11 # 0.019s
euler_12 # 4.258s
euler_13 # 0.077s
euler_14 # 24.853s
euler_15 # 1.612s
euler_16 # 0.768s
euler_17 # 0.026s
euler_18 # 1.695s
euler_32 # 2.407s
euler problems # 153.222s

RUN#2: g++ -s -O2 -fpermissive -Wall *.c -o flang
euler_1 # 0.003s
euler_2 # 0.000s
euler_3 # 0.161s
euler_4 # 0.032s
euler_5 # 0.005s
euler_6 # 0.000s
euler_7 # 2.803s
euler_8 # 0.041s
euler_9 # 0.919s
euler_10 # 117.314s
euler_11 # 0.019s
euler_12 # 4.396s
euler_13 # 0.077s
euler_14 # 25.351s
euler_15 # 1.629s
euler_16 # 0.757s
euler_17 # 0.026s
euler_18 # 1.651s
euler_32 # 2.401s
euler problems # 157.585s

RUN#3: g++ -Ofast -fpermissive -Wall *.c -o flang
euler_1 # 0.003s
euler_2 # 0.001s
euler_3 # 0.154s
euler_4 # 0.032s
euler_5 # 0.005s
euler_6 # 0.000s
euler_7 # 2.767s
euler_8 # 0.037s
euler_9 # 0.887s
euler_10 # 112.215s
euler_11 # 0.019s
euler_12 # 4.187s
euler_13 # 0.076s
euler_14 # 24.827s
euler_15 # 1.579s
euler_16 # 0.764s
euler_17 # 0.026s
euler_18 # 1.573s
euler_32 # 2.129s
euler problems # 151.280s

RUN#4: conversion *.c -> *.c++ : g++ -Ofast -fpermissive -Wall *.c++ -o flang
euler_1 # 0.003s
euler_2 # 0.001s
euler_3 # 0.152s
euler_4 # 0.032s
euler_5 # 0.005s
euler_6 # 0.000s
euler_7 # 2.784s
euler_8 # 0.038s
euler_9 # 0.911s
euler_10 # 118.174s
euler_11 # 0.019s
euler_12 # 4.249s
euler_13 # 0.077s
euler_14 # 25.226s
euler_15 # 1.599s
euler_16 # 0.759s
euler_17 # 0.025s
euler_18 # 1.696s
euler_32 # 2.597s
euler problems # 158.348s

C

RUN#1: gcc -O3 -Wall *.c -o flang
euler_1 # 0.003s
euler_2 # 0.001s
euler_3 # 0.153s
euler_4 # 0.032s
euler_5 # 0.005s
euler_6 # 0.000s
euler_7 # 2.771s
euler_8 # 0.037s
euler_9 # 0.885s
euler_10 # 113.996s
euler_11 # 0.019s
euler_12 # 4.299s
euler_13 # 0.078s
euler_14 # 25.288s
euler_15 # 1.601s
euler_16 # 0.754s
euler_17 # 0.026s
euler_18 # 1.593s
euler_32 # 2.419s
euler problems # 153.961s

RUN#2: gcc -s -O2 -Wall *.c -o flang
euler_1 # 0.003s
euler_2 # 0.001s
euler_3 # 0.154s
euler_4 # 0.032s
euler_5 # 0.005s
euler_6 # 0.000s
euler_7 # 2.817s
euler_8 # 0.039s
euler_9 # 0.905s
euler_10 # 118.086s
euler_11 # 0.019s
euler_12 # 4.266s
euler_13 # 0.078s
euler_14 # 25.270s
euler_15 # 1.586s
euler_16 # 0.767s
euler_17 # 0.026s
euler_18 # 1.601s
euler_32 # 2.261s
euler problems # 157.914s

RUN#3: gcc -Ofast -Wall *.c -o flang
euler_1 # 0.003s
euler_2 # 0.000s
euler_3 # 0.153s
euler_4 # 0.032s
euler_5 # 0.005s
euler_6 # 0.000s
euler_7 # 2.788s
euler_8 # 0.038s
euler_9 # 0.899s
euler_10 # 112.252s
euler_11 # 0.019s
euler_12 # 4.233s
euler_13 # 0.076s
euler_14 # 24.673s
euler_15 # 1.598s
euler_16 # 0.738s
euler_17 # 0.025s
euler_18 # 1.566s
euler_32 # 2.141s
euler problems # 151.239s
 
Ongelmahan näissä AAA-peleissä on se että ne on kaikki koodattu C++:lla.
How I do my Computing My favorite programming languages are Lisp and C.
John Carmackin ensimmäinen ja ainoa kunnon Quake oli C:llä.
Itselle kelpaisi C:llä koodattu AAA-peli, mutta ne on kaikki tehty noob - C:llä eli C++:lla. Pelit on kuraa, koska C++ on täysin epäonnistunut kieli.

Ei tee pätevää... Mikähän sinusta tekee pätevän yhtään mihinkään?
Lue nyt GNU:n luojan kommentit C++:sta ajatuksella, ennenkuin kommentoit tyhmiä. En Torvaldsia maininnutkaan. Sanoin että itselle kelpaisi C:llä tehty AAA-peli.

Tässä omalla ohjelmointikielellä sorttausalgoritmien benchmarkkausta, jonka implementoin C:llä. Luulen tietäväni C:stä aika paljon.
flang/sorting_algorithms_benchmark.flang at master · mystikkogames/flang · GitHub

Ihan puhtaasti siksi että C:n kääntäjä tuottaa parempaa/nopeampaa assemblyä kuin C++ kääntäjä. Miksiköh? Höh? Häh? Sitä en viitsi selittää.

Lopputuloksena: C:n paras aika: 151.239s ja C++:n 151.280s. Joten käytännössä samat ajat.


... eli lopputulemana siis kuitenkin suot luvan maailman pelitaloille jatkaa pelikehitystä C++ pohjalta? Siitäkin huolimatta että Stallmanin mielestä syntaxi on ruma? :kahvi:
 
... eli lopputulemana siis kuitenkin suot luvan maailman pelitaloille jatkaa pelikehitystä C++ pohjalta? Siitäkin huolimatta että Stallmanin mielestä syntaxi on ruma? :kahvi:
Tässä vertailtiin C ohjelman suorituskykyä tai oikeammin C++ ja C kääntäjän optimoinnin tehokkuutta toisiinsa. Eiköhän pelinkehityskielen aika pitkälle määrittele kehitysalustan rajapintojen tarjoamat sidokset eri ohjelmointikielelle.
 
Tässä vertailtiin C ohjelman suorituskykyä tai oikeammin C++ ja C kääntäjän optimoinnin tehokkuutta toisiinsa. Eiköhän pelinkehityskielen aika pitkälle määrittele kehitysalustan rajapintojen tarjoamat sidokset eri ohjelmointikielelle.
AP:n argumentti siis nimenomaa oli, että kaikki pitää tehdä C:llä koska sillä tulee automaattisesti parempi lopputulos koska kääntäjä on niin amazing.
 
AP:n argumentti siis nimenomaa oli, että kaikki pitää tehdä C:llä koska sillä tulee automaattisesti parempi lopputulos koska kääntäjä on niin amazing.
Jos jotakin niin testi todisti että GCC:n C ajoympäristö sisältää vähemmän pläskiä kuin C++ ympäristö. Väite kääntäjän eroista on hieman kaukaa haettu varsinkin kun käytetään samaa kääntäjää. GCC projekti luopui jo tovi sitten perinteisestä front back rakenteesta modernimpaan single pass ja HPA rakenteeseen.
 
Hyvin luonnollisia nämä tulokset. Samalla kääntäjällä käännetään sama koodi, ei sillä ole väliä onko kääntäjän kytketty päälle tuki ominaisuuksilla joita tämä koodi ei käytä

Mielenkiintoinen olisi sitten vertailu, että kirjoitettaisiin joku saman asian tekevä koodi käyttäen esim. C++n stringiä vs C:n char*ä, ja jotain tietorakenteita joita C:llä sortattaisiin esim. sort-funktiolla ja C++ssa std::sortilla.


Oleellisin ero Cn ja C++lla kirjoitettujen ohjelmien välillä tosin suorituskyvyssä käytännössä usein tulee siitä, että C++lla on helpompi kirjoittaa hidasta koodia (joko ihan huolimattomuuttaan, tai sitten osaamattomuuttaan, piittaamattuuttaan(mennään koodin "kauneus" suorituskyvyn edellä) tai sitten ihan vaan sen takia että se hidas koodi on nopeampi ja tuottavampi kirjoittaa, ja koodarin aika on kallista ja koodi halutaan pihalle nopeasti. (käytännössä usein näiden kaikkien yhdistelmää)).

C:llä sitä hidasta koodia kirjoittaessaan tajuaa kirjoittavansa hidasta koodia, kun joutuu kirjoittamaan ylimääräisiä funktiokutsuja yms.

C++ taas piilottaa niitä funktiokutsuja esim. operator overloadingilla ja rakentajilla siten että joku koodirivi joka näyttää "yhdeltä perusoperaatiolta" voikin todellisuudessa sisältää kutsun vaikka kuinka pitkään ja hitaaseen rutiiniin.


Eli siis, C++ mahdollistaa koodarille suuremman tuottavuuden kirjoittamalla nopeammin hidasta koodia, C ei tätä mahdollista, vaan pakottaa aina kirjoittamaan pienellä tuottavuudella nopeaa koodia.

Mutta jos C++aa kirjoittaa "suorituskyky edellä" niin sillä ei häviä yhtään Clle.
 
Viimeksi muokattu:
C++:han pitää sisällään C:n joten aina voi sanoa että C++ on parempi tai vähintään yhtä hyvä. Mutta kuten edellä mainittiin C:llä on luontevampaa tehdä nopeaa koodia. C++:han on vain "kuorrutetta" C:n päälle jota ilmankin pystyy kaiken tekemään mutta se vain on työläämpää.
 
C++:han pitää sisällään C:n joten aina voi sanoa että C++ on parempi tai vähintään yhtä hyvä. Mutta kuten edellä mainittiin C:llä on luontevampaa tehdä nopeaa koodia. C++:han on vain "kuorrutetta" C:n päälle jota ilmankin pystyy kaiken tekemään mutta se vain on työläämpää.
Tuo ei tainnut koskaan pitää paikkaansa ihan viimeisen päälle, ja ainakin nykyään ihmiset puhuvat jo suhteellisen isoistakin eroista. Tiedä sitten, kun minulta löytyy molemmista vain ihan perusosaaminen, mutta joka tapauksessa argumenttisi ei ainakaan ihan kokonaan pidä paikkaansa.
 
C90 ja C++98 ovat jokseenkin vielä yhteensopivia. Linkkaustasolla edelleen, mutta uusin C11 mukainen koodi ei enää C++17 kääntäjällä välttämättä käänny. Ajoympäristö on ollut eri sitten cfrontin.
 
Hyvin luonnollisia nämä tulokset. Samalla kääntäjällä käännetään sama koodi, ei sillä ole väliä onko kääntäjän kytketty päälle tuki ominaisuuksilla joita tämä koodi ei käytä
...
C:llä sitä hidasta koodia kirjoittaessaan tajuaa kirjoittavansa hidasta koodia, kun joutuu kirjoittamaan ylimääräisiä funktiokutsuja yms.

C++ taas piilottaa niitä funktiokutsuja esim. operator overloadingilla ja rakentajilla siten että joku koodirivi joka näyttää "yhdeltä perusoperaatiolta" voikin todellisuudessa sisältää kutsun vaikka kuinka pitkään ja hitaaseen rutiiniin.


Eli siis, C++ mahdollistaa koodarille suuremman tuottavuuden kirjoittamalla nopeammin hidasta koodia, C ei tätä mahdollista, vaan pakottaa aina kirjoittamaan pienellä tuottavuudella nopeaa koodia.

Mutta jos C++aa kirjoittaa "suorituskyky edellä" niin sillä ei häviä yhtään Clle.

Tätä lausumaa tukee minunkin kokemukseni.

Olen jopa kohdannut suuren suomalaisen it-yhtiön omaan käyttöönsä tekemän kirjaston, jossa käytettiin CString -muuttujaa puskurin tallettamiseen. Ongelma? Muuttujan sisältö rakennettiin merkki kerrallaan ketjuttamalla eikä stringillä ollut edes kasvuarvoa eli jokainen merkki aiheutti uuden puskurin varaamisen, vanhan vapauttamise jne. Eli 20.000 merkin puskurin kopiointi vaati 200.010.000 merkin siirron, vapautuksen ja varauksen. Vastuulliset ohjelmoijat eivät pitäneet siitä, ehdotin koodiin muutosta. "Kyllä tämä on eksakti tiede!" julistettiin. Niinpä, mutta kyllä virheet silti pitää korjata. Tämä tapahtui vuonna 1995. Eli allekirjoitan "hkultala:a". CStringillä on metodi, jolla haluamansa suuruisen puskurin voi varata. Eli pienellä korjauksella selvittiin. Jos siis sinne luokkien sisään tulee vääryyksiä, niin ne voivat jäädä piiloon.

C++ rupeaa tuottamaan, kun hyödynnetään periytymistä ja geneeristä ohjelmointia: stl ja muita. Oliojärjestelmä on helppo ylläpitää, mutta se on vaativa suunnitella.
 
Viimeksi muokattu:
C++:han pitää sisällään C:n joten aina voi sanoa että C++ on parempi tai vähintään yhtä hyvä. Mutta kuten edellä mainittiin C:llä on luontevampaa tehdä nopeaa koodia. C++:han on vain "kuorrutetta" C:n päälle jota ilmankin pystyy kaiken tekemään mutta se vain on työläämpää.

Kuorrutus ei ehkä nykyään ole oikea termi. C++ templatet muuttavat sen omaksi paradigmakseen. Muinoin se oli vain Kuorrutus, mutta ei enää. C++ on täysin eri kieli kuin C.

Inline -funktiot mahdollistavat laajemman optimoinnin, vai onko C:ssä nykyisin ne?

Voisi myös sanoa, että C++ n täysi hyöndyntäminen estää huonon koodin tekemisen. Huonoa koodia on tosi vaikea saada toimimaan. Konsulttina näki kaikenlaista.
 
Inline -funktiot mahdollistavat laajemman optimoinnin, vai onko C:ssä nykyisin ne?

Voisi myös sanoa, että C++ n täysi hyöndyntäminen estää huonon koodin tekemisen. Huonoa koodia on tosi vaikea saada toimimaan. Konsulttina näki kaikenlaista.
Inline fucntion tuli virallisesti C99 ja epävirallisesti paljon ennen sitä.
En nyt sanoisi C++ estää huonon koodin tekemisen mutta kyllähän se ohjaa parempaan suuntaan.
 
Voisi myös sanoa, että C++ n täysi hyöndyntäminen estää huonon koodin tekemisen. Huonoa koodia on tosi vaikea saada toimimaan. Konsulttina näki kaikenlaista.
Riippuu huonon määritelmästä. Puhdas C toteutus on äkkiä kooltaan kymmenesosan vastaavasta C++ sovelluksesta ja pahimmillaan sama pätee suoritusnopeuteen.

Templatet, futuurit, lambdat ja älykkäät osoittimet tekevät koodin vianselvityksestä työlästä.

Nyrkkisääntönä mitä ilmaisuvoimaisempi kieli, sitä huonompaa koodia sillä on mahdollista kirjoittaa.
 
Riippuu huonon määritelmästä. Puhdas C toteutus on äkkiä kooltaan kymmenesosan vastaavasta C++ sovelluksesta ja pahimmillaan sama pätee suoritusnopeuteen.

Templatet, futuurit, lambdat ja älykkäät osoittimet tekevät koodin vianselvityksestä työlästä.

Nyrkkisääntönä mitä ilmaisuvoimaisempi kieli, sitä huonompaa koodia sillä on mahdollista kirjoittaa.

Totta nuokin. Huonolla tarkoitan vaikeasti ylläpidettävää. Ylläpitohan se on, joka maksaa järjestelmän elinkaaren aikana.

Mihin kokoon viittaat? Source -koodiin vai objectiin? Oman kokemukseni mukaan C++ on tiiviimpää. Esim. 100.000 riviä C++:aa tekee enemmän kuin sama määrä C:tä. Lasken näissä tilastoinneissa ";" = rivi eli ei kommentteja laskennassa. Kommenttien määrä kertoo sitten omat juttunsa.

Itse pyrin aina käyttämään tarkoitukseen sopivaa välinettä. Kielikin on yksi väline eli en karsasta mitään kieltä, mutta tietysti voi vanha tuttu osoittautua "sopivaksi", vaikka näin ei jonkun muun mielestä olisikaan.

Ehkä meillä joskus on käytössä väline, jolla jokainen voi katsoa koodia omana lempikoodinaan eli väline muuntaa koodia käyttäjän mukaan.
 
Ajossa olevan binäärin muistijälkeen. Muulla ei yleisessä tapauksessa ole väliä kun puhutaan suorituskyvystä.

Koolla ja suorituskyvyllä ei kyllä ole suoraa korrelointia, semminkin kun käytetään samaa kääntäjää. Prosessori vaikuttaa siihen, mitä käskykantaa käytetään. Samassa prosessorissa toimii vain yksi käskykanta eli kielestä riippumatta syntyy samat konekieliset käskyt.

Binäärin muistijälki ei ole suoraan verrannollinen tehokkuuteen. Esim. GCC:llä kun optimoi nopeuteen, niin se generoi usein loopit auki peräkkäisiksi käskyiksi, koska se on nopeampi ajaa kuin looppina. Ehkä C:ssä on samanlaiset optimoinnit?

Suurempi binäärikoko syntyy kirjastoista, joista C++:ssa useammin ladataan staattisiksi osiksi paloja. Tämä voi joko nopeuttaa suoritusta tai hidastaa sitä, tapauksesta riippuen - esim cache-hit ei osu, koska cachen koko ei riitä pitämään koko run-unitia muistissa. Tämä sama voi tietysti toteutua myös kirjastokutsujen kohdalla.

Mitä suuremmasta järjestelmästä on kysymys, sitä pienempi osuus on kielikohtaisten kirjastojen binäärillä.
 
Kun edes pohditaan C kielen käyttöä, ollaan sulautetuissa sovelluksissa. Tästä vaikka kevyttä lukemista asiasta https://www.embedded.com/electronic...to-trouble--Jack---s-Top-Ten-----Number-Eight

Kuitenkin otsikkona on C VS C++? Oliko siis tarkoitus keskustella C++:n soveltuvuudesta sulautettuihin järjestelmiin? Itse olen kyllä käyttänyt C:tä silloin, kun C++ ei vielä ollut olemassa. Konekielellä aloitin vuonna 1972, nyt olen eläkkeellä.

En olisi uskonut että muistia upotetuissa on edelleen niin vähän, että pitäisi koodata assembly:lla. Sen korvaamiseen kyllä ymmärrän C:n käytön. 1972 koneen muisti oli 3.000 merkkiä, siitä kyllä käytettiin kaikki bitit.
 
Kun edes pohditaan C kielen käyttöä, ollaan sulautetuissa sovelluksissa. Tästä vaikka kevyttä lukemista asiasta How embedded projects run into trouble: Jack’s Top Ten – Number Eight

Hauska sattuma! Kirjoitin aiemmin, että aloitin 1972 ohjelmoinnin. Sitten menin lukemaan antamaasi linkkiä ja siellä se taas oli: vuosi 1972. Itse en ohjelmoinut pdp-11:tä, mutta vaimo taisi, se oli 1980 -luvulla.

Tekstihän kertoo kurittoman ohjelmointikulttuurin aiheuttamista ongelmista. Ei se tuomitse C:tä tai C++:aa. Kaikki mikä tehdään huonosti, aiheuttaa ongelmia. Ei sitä pysty ohjelmointikielellä estämään.

Sulautetuissa järjestelmissä kannattaa käyttää räätälöityjä kirjastoja eikä kannata käyttää io-streamejä. Niistä tulee helposti turhaa binääriä, mutta luokkia ja periytymistä kannattaa hyödyntää. Ei käytetty kieli vaikuta lopullisen binäärin kokoon, jos sitä kieltä osaa käyttää. Perinnällä voi uudelleen käyttää koodia, jolloin sen ylläpito helpottuu. Suunnittelu on kylläkin vaativaa.

Lasketaanko prosessinohjaus sulautettuihin? Esim. Allen-Bradleyn liukuhihnojen, flippereiden ja sellaisten ohjaus. Semmoisiakin tein joskus 1988-1990. Sitä ohjelmoitiin Basicillä. Muistia muutama kilo. Logiikkaa oli ympäriinsä. Tein siihen myös linjan salakuuntelijan, joka siirsi tietoa prosessista main-frameen. Kuuntelu toimi MS-DOSSISSA. En muista oliko C vai C++-toteutus. Main-framessa Cobol. Työasemissa C++.
 
Tekstihän kertoo kurittoman ohjelmointikulttuurin aiheuttamista ongelmista. Ei se tuomitse C:tä tai C++:aa. Kaikki mikä tehdään huonosti, aiheuttaa ongelmia. Ei sitä pysty ohjelmointikielellä estämään.
En minäkään kumpaakaan tuomitse, oli tarkoituskin korostaa sitä että ei se kieli ongelmia aiheuta, vaan sen käyttö väärään hommaan tai väärällä tavalla.
 

Statistiikka

Viestiketjuista
258 788
Viestejä
4 496 575
Jäsenet
74 292
Uusin jäsen
GeGGoZ

Hinta.fi

Back
Ylös Bottom