C vs C++

Viestiketju alueella 'Ohjelmointi, pelikehitys ja muu sovelluskehitys' , aloittaja mystikkogames, 19.12.2017.

  1. mystikkogames

    mystikkogames

    Viestejä:
    102
    Rekisteröitynyt:
    05.11.2017
    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
     
  2. teppo mörkö

    teppo mörkö

    Viestejä:
    419
    Rekisteröitynyt:
    17.10.2016

    ... eli lopputulemana siis kuitenkin suot luvan maailman pelitaloille jatkaa pelikehitystä C++ pohjalta? Siitäkin huolimatta että Stallmanin mielestä syntaxi on ruma? :kahvi:
     
  3. jive

    jive

    Viestejä:
    510
    Rekisteröitynyt:
    27.12.2016
    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.
     
  4. Proscribo

    Proscribo

    Viestejä:
    284
    Rekisteröitynyt:
    16.10.2016
    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.
     
  5. jive

    jive

    Viestejä:
    510
    Rekisteröitynyt:
    27.12.2016
    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.
     
  6. hkultala

    hkultala

    Viestejä:
    3 075
    Rekisteröitynyt:
    22.10.2016
    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: 24.12.2017
    zZzz, Wapaaherra, Kidov ja 1 muu käyttäjä tykkää tästä.
  7. JaniKari

    JaniKari

    Viestejä:
    228
    Rekisteröitynyt:
    28.12.2016
    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ää.
     
  8. Xiyng

    Xiyng

    Viestejä:
    969
    Rekisteröitynyt:
    19.10.2016
    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.
     
  9. jive

    jive

    Viestejä:
    510
    Rekisteröitynyt:
    27.12.2016
    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.
     
  10. Aaro Penttiä

    Aaro Penttiä

    Viestejä:
    13
    Rekisteröitynyt:
    02.09.2018
    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: 04.09.2018
  11. Aaro Penttiä

    Aaro Penttiä

    Viestejä:
    13
    Rekisteröitynyt:
    02.09.2018
    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.
     
  12. JaniKari

    JaniKari

    Viestejä:
    228
    Rekisteröitynyt:
    28.12.2016
    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.
     
  13. jive

    jive

    Viestejä:
    510
    Rekisteröitynyt:
    27.12.2016
    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.
     
  14. Aaro Penttiä

    Aaro Penttiä

    Viestejä:
    13
    Rekisteröitynyt:
    02.09.2018
    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.
     
  15. jive

    jive

    Viestejä:
    510
    Rekisteröitynyt:
    27.12.2016
    Ajossa olevan binäärin muistijälkeen. Muulla ei yleisessä tapauksessa ole väliä kun puhutaan suorituskyvystä.
     
  16. Aaro Penttiä

    Aaro Penttiä

    Viestejä:
    13
    Rekisteröitynyt:
    02.09.2018
    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ä.
     
  17. jive

    jive

    Viestejä:
    510
    Rekisteröitynyt:
    27.12.2016
  18. Aaro Penttiä

    Aaro Penttiä

    Viestejä:
    13
    Rekisteröitynyt:
    02.09.2018
    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.
     
  19. Aaro Penttiä

    Aaro Penttiä

    Viestejä:
    13
    Rekisteröitynyt:
    02.09.2018
    Kukahan on tämä AP? En ainakaan minä!
     
  20. Paapaa

    Paapaa

    Viestejä:
    1 446
    Rekisteröitynyt:
    17.10.2016
    Tuo kommentti on kirjoitettu ennen kuin olet edes rekisteröitynyt palstalle... "AP" ("alkuperäinen postaaja") tarkoittaa ketjun ensimmäisen viestin kirjoittajaa. Englanniksi OP "original poster".
     
  21. Aaro Penttiä

    Aaro Penttiä

    Viestejä:
    13
    Rekisteröitynyt:
    02.09.2018
    Hyvä! Ei ole sitten dementia iskenyt!
     
    Paapaa tykkää tästä.
  22. Aaro Penttiä

    Aaro Penttiä

    Viestejä:
    13
    Rekisteröitynyt:
    02.09.2018
    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++.
     
  23. Aaro Penttiä

    Aaro Penttiä

    Viestejä:
    13
    Rekisteröitynyt:
    02.09.2018
    Myönnän pienen provosoinnin.
     
  24. jive

    jive

    Viestejä:
    510
    Rekisteröitynyt:
    27.12.2016
    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.