Python suorituskyky

eikäsitä

Aivan käsittämättömän surkea. Jos laitetaan pikseli näkymään(Pygame) ja liikutellaan rivi kerrallaan alas näytön alareunaan niin suorituskyky on 1980-luvun Amiga(assembler) tasoa???? Kestää kolme sekuntia ainakin. Mtien tämä voi olla totta nykyisillä prosessoreilla? Vaikka on tulkkaava kieli niin miten kaikki se teho voidaan hukata?

42

493

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • Eihän tuossa ole mitään tehohävikkiä. Tässä mun näytöllä on 1200px pystysuunnassa, ja ruudunpäivitys 60 ruutua sekunnissa, että pikseli kerrallaan kun liikuttaa niin tuossa pitäisi mennä 20 sekuntia.

      Amigalla oli 50 ruutua sekunnissa ja pikseleitä pystysuunnassa 200px, että siinä pitäisi mennä 4 sekuntia.

      Joka tapauksessa kuullostaa siltä, että yrität tehdä jotain käsittämätöntä.

      Harvemmin missään on mitään suorituskykyongelmaa ellei nyt oikeasti yritetä ohjelmoida jotain käsittämätöntä. Amigassa kyllä oli omat rajoitteensa.

    • Python-on-OK

      Minkä kokoista ikkunaa käytät testissä ?

      Minä testasin 800 x 800 pixelsiä ja sain ajaksi 0.359131097794 sekuntia. Amiga(assembler) tasot ja ajat on minulle tuntemattomia.

      Commodore 64 näytön resoluutio oli vain 25 rivi ja 40 saraketta, josta voidaan juontaa 25x8=200 ja 40x8=320, eli Commodore 64 näyttö oli 200 pixelsiä korkea ja 320 pixelsiä leveä. Ja tuohon python käytti aikaa 0.219390153885 sekuntia, minkä verran Commodore 64 siihen käytti ei ole minulla tiedossa enkä saa sitä testattua.

      Mielestäni Python on erittäin suorituskykyinen.

      Linux Mint 18 Sarah
      Xfce 64-bit

      • amiga500

        Amigassa HiRes Laced
        640×400 @ 60Hz (NTSC)
        640×512 @ 50Hz (PAL) up to 16 colors
        4096 color palette


      • enkäsitä

        Laitoin ikkunan kooksi nyt 800*800 ja piirretään ikkunaan pikseliä vasemmalta oikealle ylhäältä alkaen pikseli kerrallaan eli 640 000 kappaletta ja yhden ruudun piirto kestää 30 sek.

        Piirretyn pikselin päivitys tehdään
        naytto.set_at((x, y), color)
        pygame.display.update(x,y,x,y)
        eli päivitetään vain tuo pikselin kokoinen alue kun pygame.display.flip() on niin hidas.

        Oletin että tuon testimuotoisen ruuduntäytön voisi piirtää kenties 30 kertaa sekunnissa mutta yksi ruutu kestääkin piirtää sen 30 sek!

        Core i5-6500 käyttää yhtä ydintä n.30% ja GTX 950 60%.


      • Python-on-OK
        enkäsitä kirjoitti:

        Laitoin ikkunan kooksi nyt 800*800 ja piirretään ikkunaan pikseliä vasemmalta oikealle ylhäältä alkaen pikseli kerrallaan eli 640 000 kappaletta ja yhden ruudun piirto kestää 30 sek.

        Piirretyn pikselin päivitys tehdään
        naytto.set_at((x, y), color)
        pygame.display.update(x,y,x,y)
        eli päivitetään vain tuo pikselin kokoinen alue kun pygame.display.flip() on niin hidas.

        Oletin että tuon testimuotoisen ruuduntäytön voisi piirtää kenties 30 kertaa sekunnissa mutta yksi ruutu kestääkin piirtää sen 30 sek!

        Core i5-6500 käyttää yhtä ydintä n.30% ja GTX 950 60%.

        Kyllä noin hyvällä koneella 30 kertaa sekunnissa on lähempänä totuutta kuin että siihen menisi 30 sekuntia. Tässä tapauksessa sillä kumpaa pygame.display.update() vai pygame.display.flip() käytät ei ole suurta merkitystä.

        Tarkista ajan näyttö / otto / laskenta, siitä Python spritestä, pakko olla virhe.

        Linux Mint 18 Sarah
        Xfce 64-bit


      • eikäsitä

        "Tarkista ajan näyttö / otto / laskenta, siitä Python spritestä, pakko olla virhe."
        No ei siinä voi olla virhettä. Kyllähän 30 sekuntia mittaa vaikka käkikellosta. Ehkä virhe on siinä, osasinko selittää testin oikein.

        Aloitetaan 800*800 ikkunan täyttö x=0, y=0 kasvatetaan x:sää aina yhdellä, piirretään pikseli. Kun x=800, nollataan x ja lisätään y 1 kunnes kaikki rivit ja sarakkeet on käyty läpi. Eli 640 000:n pikselin värin vaihtaminen kestää 30 sekuntia. Eli FPS on 0,033.

        Ehkä nuo pikselit pitäisi ensin tehdä taulukkoon ja sitten kerralla kopioida taulukko näyttömuistiin. " pygame.surfarray.pixels2d()
        Tai sitten säikeistää tehtävä ja käyttää tuplabufferointia? Tiedä en. Tai sitten vaihtaa c/c .


      • enkäsitä kirjoitti:

        Laitoin ikkunan kooksi nyt 800*800 ja piirretään ikkunaan pikseliä vasemmalta oikealle ylhäältä alkaen pikseli kerrallaan eli 640 000 kappaletta ja yhden ruudun piirto kestää 30 sek.

        Piirretyn pikselin päivitys tehdään
        naytto.set_at((x, y), color)
        pygame.display.update(x,y,x,y)
        eli päivitetään vain tuo pikselin kokoinen alue kun pygame.display.flip() on niin hidas.

        Oletin että tuon testimuotoisen ruuduntäytön voisi piirtää kenties 30 kertaa sekunnissa mutta yksi ruutu kestääkin piirtää sen 30 sek!

        Core i5-6500 käyttää yhtä ydintä n.30% ja GTX 950 60%.

        Eli siis et piirtänyt yhtä pikseliä vaan piirsit 640000 pikseliä.

        No, joka tapauksessa teet asiat moninkertaisesti väärin.

        1. Pikseleillä täyttöön käytetään rajapintakutsua: https://www.pygame.org/docs/ref/surface.html#pygame.Surface.fill

        Tuossa ei tehdä 640000 rajapintakutsua vaan yksi kun piirretään.

        2. Varmaan kannattaisi nyt miettiä sitäkin, että mitä yritetään saada aikaiseksi ja onko työkalu oikein valittu. Kyllä jonkun ikkunan värin vaihtaa helpomminkin.


      • eikäsitä kirjoitti:

        "Tarkista ajan näyttö / otto / laskenta, siitä Python spritestä, pakko olla virhe."
        No ei siinä voi olla virhettä. Kyllähän 30 sekuntia mittaa vaikka käkikellosta. Ehkä virhe on siinä, osasinko selittää testin oikein.

        Aloitetaan 800*800 ikkunan täyttö x=0, y=0 kasvatetaan x:sää aina yhdellä, piirretään pikseli. Kun x=800, nollataan x ja lisätään y 1 kunnes kaikki rivit ja sarakkeet on käyty läpi. Eli 640 000:n pikselin värin vaihtaminen kestää 30 sekuntia. Eli FPS on 0,033.

        Ehkä nuo pikselit pitäisi ensin tehdä taulukkoon ja sitten kerralla kopioida taulukko näyttömuistiin. " pygame.surfarray.pixels2d()
        Tai sitten säikeistää tehtävä ja käyttää tuplabufferointia? Tiedä en. Tai sitten vaihtaa c/c .

        Semmoinen yleisohje ohjelmoinnissa on, että vältetään kaikennäköisiä silmukoita, ehtoja, sijoituksia ja minimoidaan niitä rajapintakutsuja. Toisin sanoen tehdään rakenteellisesti siistiä koodia funktioina niin maagisesti kaikki suorituskykyongelmat katoavat. Hyvin löytyi sitä suorituskykyä Amigastakin, oli vain vähemmän ja oli kömpelömpää ohjelmoida mutta onhan se tekniikka nyt mennyt eteenpäin toki.


      • eikäsitä

        "Eli siis et piirtänyt yhtä pikseliä vaan piirsit 640000 pikseliä."
        Kuka voi käsittää piirtämisestä yhtä pikseliä kun kerrottiin että kyseessä on 640 000 Pikseliä?
        Ei kyse ole mistään ikkunan värin vaihtamisesta vaan kyseisen ikkunan kaikkien pikseleiden värin vaihtamisesta!

        Ette te tajua!


      • eikäsitä kirjoitti:

        "Eli siis et piirtänyt yhtä pikseliä vaan piirsit 640000 pikseliä."
        Kuka voi käsittää piirtämisestä yhtä pikseliä kun kerrottiin että kyseessä on 640 000 Pikseliä?
        Ei kyse ole mistään ikkunan värin vaihtamisesta vaan kyseisen ikkunan kaikkien pikseleiden värin vaihtamisesta!

        Ette te tajua!

        Kirjoitetit näin: "Jos laitetaan pikseli näkymään(Pygame) ja liikutellaan rivi kerrallaan alas näytön alareunaan"

        Eli tuon tekstin mukaan piirsit yhden pikselin mitä liikutat alaspäin rivi kerrallaan. Ruudunpäivitys nopeus kun on 60 ruutua sekunnissa niin se olisi 60 riviä sekunnissa.

        Nyt sitten oli kyse siitä, että olit jostain syystä tehnyt silmukan jota iteroidaan 640000 kertaa ja ihmettelet miksi siinä menee aikaa vaikka saat ne pikselit täytettyä sillä rajapintakutsulla jota tarvitsee kutsua kerran.

        Eli sieltä jäisi semmoinen 640000 iteraation silmukka pois kun käyttäisi sitä Surface.fill kutsua ja aikaa menisi sitten varmaan noin 16ms, eli se aika mitä ruudunpäivityksessä kestää.


      • eikäsitä kirjoitti:

        "Eli siis et piirtänyt yhtä pikseliä vaan piirsit 640000 pikseliä."
        Kuka voi käsittää piirtämisestä yhtä pikseliä kun kerrottiin että kyseessä on 640 000 Pikseliä?
        Ei kyse ole mistään ikkunan värin vaihtamisesta vaan kyseisen ikkunan kaikkien pikseleiden värin vaihtamisesta!

        Ette te tajua!

        Tämä lienee malliesimerkki siitä, että suorituskyky ei johdu niinkään välineistä vaan ohjelmoijasta. Pitää jättää ne silmukat, ehdot, kutsut muualle yms. minimiin niin kummasti sitä vauhtia löytyy yllinkyllin.


      • enkäsitä

        Niin rivi kerrallaan ja yksi rivi on 800 pikseliä. Se kertaa 800 on 640 000 pikseliä. Surface.fill (Fill the Surface with a solid color)täyttää ikkunan annetulla RGB-arvolla eihän sitä voi käyttää ennenkun joka pikselin väri on laskettu!
        Ette te kukaan tajua mistä on kyse!


      • enkäsitä kirjoitti:

        Niin rivi kerrallaan ja yksi rivi on 800 pikseliä. Se kertaa 800 on 640 000 pikseliä. Surface.fill (Fill the Surface with a solid color)täyttää ikkunan annetulla RGB-arvolla eihän sitä voi käyttää ennenkun joka pikselin väri on laskettu!
        Ette te kukaan tajua mistä on kyse!

        "Niin rivi kerrallaan ja yksi rivi on 800 pikseliä. Se kertaa 800 on 640 000 pikseliä. Surface.fill (Fill the Surface with a solid color)täyttää ikkunan annetulla RGB-arvolla eihän sitä voi käyttää ennenkun joka pikselin väri on laskettu! Ette te kukaan tajua mistä on kyse!"

        No määrittele se ongelma sitten.

        Se ei ollut yhden pikselin siirtäminen ylhäältä alas. Eikä se nyt ollut värin vaihtaminen kaikista pikseleistä.

        Eli mitä siis yrität saada aikaiseksi? Olen jokseenkin varma, että tuossa ei suorituskyky rajoita.


      • etymmärrämitään

        Luulitko pässi että kultakin riviltä käsitellään vain yksi pikseli? Ei vaan kaikki 800 pikseliä!


      • etymmärrämitään kirjoitti:

        Luulitko pässi että kultakin riviltä käsitellään vain yksi pikseli? Ei vaan kaikki 800 pikseliä!

        No sinähän itse sanoit että pikseli.

        Sitten pitää kysyä, että miksi käsittelet pikseli kerrallaan etkä koko kuvaa kerrallaan, olisi jotain 640000 rajapintakutsua vähemmän.


      • enkäsitä
        M-Kar kirjoitti:

        Eli siis et piirtänyt yhtä pikseliä vaan piirsit 640000 pikseliä.

        No, joka tapauksessa teet asiat moninkertaisesti väärin.

        1. Pikseleillä täyttöön käytetään rajapintakutsua: https://www.pygame.org/docs/ref/surface.html#pygame.Surface.fill

        Tuossa ei tehdä 640000 rajapintakutsua vaan yksi kun piirretään.

        2. Varmaan kannattaisi nyt miettiä sitäkin, että mitä yritetään saada aikaiseksi ja onko työkalu oikein valittu. Kyllä jonkun ikkunan värin vaihtaa helpomminkin.

        Minä sanoin aloituksessa laitetaan pikseli näkymään(Pygame) ja liikutellaan rivi kerrallaan alas näytön alareunaan(vasemmalta oikealle, ylhäältä alas). Se pikselin "liikuttaminen" on aivan sama asia kuin sen pikselin RGB-arvon muuttaminen! Kun "liikutetaan yhtä pikseliä" niin jokaisen rivin kaikkien pikseleiden(800kpl) väriarvot pitää yksitellen muuttaa ja kun näitä rivejä on 800 kpl niin silmukassa pitää 640 000 kertaa muuttaa väriarvo! Miten tuon voi käsittää väärin?


    • tervakeuhko

      3.5 GHz prosessori pystyy suorittamaan yhdellä ytimellä 3 500 000 000 kellojaksoa /sekunti. Esim assembler-käsky NOP ei tee mitään mutta kuluttaa yhden kellojakson. Tyypillinen assembler käsky voisi viedä 20-30 kellojaksoa tekemällä laskutoimituksen kahden prosessorin datarekisterin välillä, 3 500 000 000/25=140 000 000 käskyä sekunnissa. Se on niin paljon että täytyy ihmetellä miten korkeamman tason ohjelmointikielet hukkaavat yli 90% koneen resursseista! Huonoa koodausta. Ennen kun tehtiin ohjelmat assemblerilla niin kaikki hyöty otettiin prosessorista irti!

      • Kyse on siitä, että sinä hukkaat ne resurssit. Eihän tuossa ole edes mistään prosessorista kyse vaan tuossa piirrellään ruudulle asioita.

        Nykypäivänä prosessoria ei kuluteta tarpeettomasti silmukoihin vaan tehdään enemmän asioita yhdellä käskyllä ja oikein tehtynä sen yhden käskyn prosessoi massiivisesti rinnakkaistettuna GPU. GPU:ssa voi olla tuhansia ytimiä jotka laskee samanaikaisesti.

        Annoin ohjeen siihen miten aika kutistuu yhdellä käskyllä varmaan 180 kertaiseksi, että temppu onnistuu tuolla PyGamellakin.

        Tosiasiassa PyGame on jo vähän vanhaa tekniikkaa. Viimeiset 6v fronttikoodaukseen on ollut sopivampiakin työkaluja mutta tässä tapauksessa vika näyttäisi olevan ohjelmoijassa joka hukkaa resurssit 640000 iteraation silmukalla vaikka saman asian saisi tehtyä ilman silmukkaa ja saisi paljon enemmän irti.


      • Niin ja temppuhan meni täysin samalla tavalla siinä Amigassakin. Siinä oli myös blitteriksi kutsuttu toiminto ja sille annettiin käsky ja se hoiti ne täyttöoperaatiot.

        Tuo ei olennaisesti eroa tuosta PyGamen blitteristä muuten kuin PyGamella se ohjelmointi on vähemmän kömpelöä. Aivan vastaavalla tempulla homma menee korkeamman tason kutsulla.


      • enkäsitä
        M-Kar kirjoitti:

        Kyse on siitä, että sinä hukkaat ne resurssit. Eihän tuossa ole edes mistään prosessorista kyse vaan tuossa piirrellään ruudulle asioita.

        Nykypäivänä prosessoria ei kuluteta tarpeettomasti silmukoihin vaan tehdään enemmän asioita yhdellä käskyllä ja oikein tehtynä sen yhden käskyn prosessoi massiivisesti rinnakkaistettuna GPU. GPU:ssa voi olla tuhansia ytimiä jotka laskee samanaikaisesti.

        Annoin ohjeen siihen miten aika kutistuu yhdellä käskyllä varmaan 180 kertaiseksi, että temppu onnistuu tuolla PyGamellakin.

        Tosiasiassa PyGame on jo vähän vanhaa tekniikkaa. Viimeiset 6v fronttikoodaukseen on ollut sopivampiakin työkaluja mutta tässä tapauksessa vika näyttäisi olevan ohjelmoijassa joka hukkaa resurssit 640000 iteraation silmukalla vaikka saman asian saisi tehtyä ilman silmukkaa ja saisi paljon enemmän irti.

        "Eihän tuossa ole edes mistään prosessorista kyse vaan tuossa piirrellään ruudulle asioita."
        Prosessorihan se laskee että millä perusteella piirrellään ruudulle.
        "Annoin ohjeen siihen miten aika kutistuu yhdellä käskyllä varmaan 180 kertaiseksi, että temppu onnistuu tuolla PyGamellakin" Et antanut koska et ymmärtänyt ongelmaa.
        "hukkaa resurssit 640000 iteraation silmukalla vaikka saman asian saisi tehtyä ilman silmukkaa" Miten vaihdat jokaisen 640 000:n eri pikselin värin ilman silmukkaa? Siinähän pitää vaihtaa joka pikselille oma RGB-arvo.


      • enkäsitä kirjoitti:

        "Eihän tuossa ole edes mistään prosessorista kyse vaan tuossa piirrellään ruudulle asioita."
        Prosessorihan se laskee että millä perusteella piirrellään ruudulle.
        "Annoin ohjeen siihen miten aika kutistuu yhdellä käskyllä varmaan 180 kertaiseksi, että temppu onnistuu tuolla PyGamellakin" Et antanut koska et ymmärtänyt ongelmaa.
        "hukkaa resurssit 640000 iteraation silmukalla vaikka saman asian saisi tehtyä ilman silmukkaa" Miten vaihdat jokaisen 640 000:n eri pikselin värin ilman silmukkaa? Siinähän pitää vaihtaa joka pikselille oma RGB-arvo.

        "Prosessorihan se laskee että millä perusteella piirrellään ruudulle."

        Ei laske. Ei ollut edes siinä Amigassa vaan Angus piirin blitteri hoiti sen homman. PyGamessakin kutsutaan sitä blitteriä ja fillausta ja se abstraktoi sen pois, on sitten jonkun muun homma murehtia tuosta eteenpäin miten temppu tehdään raudan tai käyttiksen kanssa.

        Ja tuo PyGame on mielestäni vanhentunutta tekniikkaa muutenkin, että helpoiten se fronttipuoli käy sillä Javascriptillä ja ne shaderit kyllä hoitaa pikselinypläyksen. Siinä se funktio rinnakkaistuu suoraan sitten vaikka tuhansille coreille ja käsittelee ne pikselit.

        Prosessori lähes aina ohjailee toimintoja mutta varsinainen laskenta sitten on oma juttunsa.

        "Miten vaihdat jokaisen 640 000:n eri pikselin värin ilman silmukkaa?"

        PyGamessa vaikka sillä fill kutsulla. Tai jos tekee shaderia niin se shader funktio ammutaan niille pikseleille noin niinkuin arkkitehtuurisesssa mielessä samanaikaisesti. Käytännössä jotain poolia tai blokin käsittelyä siellä että jakaantuu niille coreille se toiminta.


    • 020202auttaaaina

      Kyllähän Pythonin nopeus on juuri niinkuin sanoit "käsittämättömän surkea". Sillä voi tehdä ohjelman simppeliä ydinlogiikkaa, ja sen vahvuus on erittäin laaja lisämoduuli-valikoima, mutta ei se tosiaan nopeudella pullistele.

      Nopein tapa piirrellä ja värittää pikseleitä on muuten shader-ohjelmointi (ks. demoja vaikka ShaderToy-sivustolta). Esim. Pythonilla toteutettu "mandelbot fractal" kuvion piirto vie useita minuutteja, shaderilla toteutettuna sama vie aikaa yhden ruudunpäivityksen verran.

      • "Kyllähän Pythonin nopeus on juuri niinkuin sanoit "käsittämättömän surkea".

        Sanoisin että homma on kiinni enemmän ohjelmoijasta. Pythonia tulisi ohjelmoida ns. oikeaoppisesti. Se vaan ei samalla tavalla pakota siihen kuin joku Haskell vaikka tekee mutta hyvin hoitaa hommansa.

        Se toki on totta, että Python on väärä työkalu fronttiohjelmointiin. Pikselin nypläykset käy kätevimmin shadereilla ja niitähän tehdään helposti korkean tason kielillä: http://cyos.babylonjs.com/

        Tuossa niitä käytetään helposti Javascriptillä ja shaderia kirjoittamalla. Se on nykyään useimmiten oikea korkeantason kieli käyttöliittymäpuolelle.

        Eikä ole Javascriptin suorituskyvyssä yleensä mitään ongelmaa. Semmoiset guidelinet tosin laittaisin, että persistenttiä dataa olisi frontissa 4 megaa, muistinvaraisia tietorakenteita enintään 16 megaa ja assetteja kuten kuvia, lähdekoodia jne. enintään 100 megaa. Videoita voi toistella lisäksi striimamalla.

        Tuollaisilla rajoitteilla suorituskyky skaalautuisi käytännössä jokaiseen laitteeseen taskukoneita myöten.


    • Python-on-OK
      • enkäsitä

        Kiitos vastauksestasi. Sekunnin osia. Mutta eihän tässä ole tarkoitus samanväristä pikseliä piirtää, eri pikseleihin tulee tietenkin eri värit. Tuon linkkaamasi koodin piirto-osan voi suorittaa yhdellä käskyllä screen.fill(color).

        Jos vaikka visualisoisi paivovoimakentän vaihteluita niin piirron tulisi tapahtua "reaaliaikaisesti" tai edes 30 fps tasolla. Mutta ei vaan Pythonin (pygamen )nopeus taida tähän riittää. M-Kar ei ymmärtänyt ollenkaan ongelmaani. Joka pikselin väri tulee laskea jonkun datan mukaan(640 000kpl/frame) tietenkin. Aloituksessa puhuin pikselin liikuttamisesta mutta sehän on sama asia kun sen värin vaihtaminen.


      • enkäsitä kirjoitti:

        Kiitos vastauksestasi. Sekunnin osia. Mutta eihän tässä ole tarkoitus samanväristä pikseliä piirtää, eri pikseleihin tulee tietenkin eri värit. Tuon linkkaamasi koodin piirto-osan voi suorittaa yhdellä käskyllä screen.fill(color).

        Jos vaikka visualisoisi paivovoimakentän vaihteluita niin piirron tulisi tapahtua "reaaliaikaisesti" tai edes 30 fps tasolla. Mutta ei vaan Pythonin (pygamen )nopeus taida tähän riittää. M-Kar ei ymmärtänyt ollenkaan ongelmaani. Joka pikselin väri tulee laskea jonkun datan mukaan(640 000kpl/frame) tietenkin. Aloituksessa puhuin pikselin liikuttamisesta mutta sehän on sama asia kun sen värin vaihtaminen.

        Niinno se ongelma nyt sitten muuttuikin siihen, että pitäisi käsitellä surfacen kaikki pikselit jollain muulla kuin bittioperaatiolla tai ja muistikopioinneilla mitä PyGamen rajapinta tarjoaa. Määrittely muuttuu kokoaika.

        Tuollaiset asiat tehdään normaalisti shadereilla. Fronttiohjelmoinnissa käytetään yleensä jotain Javascriptiä, että sillä voi hyvin ohjata hommia ja laskea shadereilla: http://cyos.babylonjs.com/


    • kokenutkaiken

      Visual Studio/DirectX. Ihan oikeasti.

      Nämä Pythonit ja Pygamet ovat harrastelijoitten virityksiä joissa suurinosa aikaa menee toimimattomuuksien selvittelyyn.

      • Valehtelet. Pythonia käytetään valtavasti ammattikäytössä ja on erittäin hyvälaatuinen ohjelma. Siinä ei käytännössä ole mitään vikoja tai toimimattomuuksia.

        PyGame taas on rakennettu SDL kirjaston varaan ja SDL on tunnetusti myös erittäin hyvälaatuinen, siitäkään ei oikein löydy vikoja.

        PyGame on oikeastaan vain wrapperi sille SDL:lle, että se PyGame itsessään ei sisällä sitä tekniikkaa. PyGamea vaan on hiottu vuodesta 2000 lähtien, että epätodennäköistä, että siinäkään olisi ongelmia kun se ei sitä logiikkaa olennaisesti lisää.

        On helppo osoittaa sinut valehtelijaksi kun mitään vikaa et ole löytänyt.


    • Tästä ketjusta tulee hyvin kyllä mieleen, että minulla ei ole ollut minkäänlaisia suorituskykyongelmia kotitietokoneiden kanssa vuosikymmeniin.

      Ensimmäinen suorituskykyongelma oli varmaankin se, kun kotitietokoneista puuttui moniajo. Enimmän aikaa se ei vaikuttanut mutta toisinaan jos piti tehdä jotain mikä vei enemmän aikaa niin silloin piti odotella.

      Toinen suorituskykyongelma oli se UART piirin yhden tavun puskuri ja se, että yhteydet eivät toimineet pakettipohjaisesti. Tuohan tarkoitti sitä, että vaikka olisi ollut moniajo niin jos halusi ottaa yhteyden johonkin niin samanaikaisesti ei tehty mitään muuta ja oli ainoastaan se yksi yhteys. Silloin odoteltiin sitä tiedon siirtymistä sitten vaikka.

      90-luvullahan noista sitten päästiin kun oli moniajo sekä IP verkko.

      Voi myös todeta sen, että kaikkeen riittänyt suorituskyky miten vain mutta datamäärä on ratkaiseva asia. Sitä voidaan käsitellä kokoajan suurempia datamääriä.

      Tuollainen pikseliesimerkki oikein hyvä, että jos ennen oli vaikka 320x200 4-bit ja yksi kuva sekunnissa, ja nykyään 3840x2160 24-bit 60 kuvaa sekunnissa niin siinähän on noin luokkaa 46656x ero datamäärässä.

    • Tyypitön_

      Siinä missä C ja Java VM:lla lauseen "x = y * z" lopputulos on käytännössä kahden muistpaikan tai rekisterin välinen kertolasku ja sijoituksena kolmanteen, niin perus Python tekee nipun funtio kutsuja, jolloin ajettavan koodin määrä on useita kertaluokia suurempi, ja sitä myöten välimuisti hutejakin tulee enemmän. Eli tulkattavuuteen ne tehot hukkuvat. Tulkin pitäisi tietää mitä tyyppiä muuttujat ovat ja osata kääntää lauseet suoraan ajattavaksi kone koodiksi, jotta homma voisi toimisa edes jotenkin joutuisasti.

      • Python tulkki sisältää tavukoodi kääntäjän, että nehän käännetään .pyc tiedostoiksi joita sitten ajetaan. Tuon koodin ajaa sitten Pythonin virtuaalikone.

        Tässä on semmoinen mahtiominaisuus, lähdekooditiedostoja voi ajaa suoraan kääntämättä niitä itse mihinkään ja se Python ympäristö sitten hoitaa sen tavukoodikääntämisen, että kiihdyttää toimintaa.

        Välimuistin määrää on niin paljon, että ei sekään pahemmin ammu huti. Ei tuollainen x = y * z vie oikein juuri mitään aikaa Pythonilta. Ei edes silloin kun sen kysyy vaikka toiselta koneelta HTTP:llä.


      • Tyypitön_
        M-Kar kirjoitti:

        Python tulkki sisältää tavukoodi kääntäjän, että nehän käännetään .pyc tiedostoiksi joita sitten ajetaan. Tuon koodin ajaa sitten Pythonin virtuaalikone.

        Tässä on semmoinen mahtiominaisuus, lähdekooditiedostoja voi ajaa suoraan kääntämättä niitä itse mihinkään ja se Python ympäristö sitten hoitaa sen tavukoodikääntämisen, että kiihdyttää toimintaa.

        Välimuistin määrää on niin paljon, että ei sekään pahemmin ammu huti. Ei tuollainen x = y * z vie oikein juuri mitään aikaa Pythonilta. Ei edes silloin kun sen kysyy vaikka toiselta koneelta HTTP:llä.

        Ajallisesti yksi käsky ei ehkä vie kauan, mutta kun se käskyn suoritus kestää Pythonissa 5-100x kauemmin mitä useimilla muilla kielillä, niin ero alkaakin ole melko huomatta. Laskusarjan minkä tuloksen Python suoltaa 1 tunnissa, suoltaa useammat muut kielet murto osassa kyseisestä ajasta.

        Jos teen seuraavan Python pätkän:

        --------------------

        def laske_summa(alku, loppu):
        x = alku
        while alku < loppu:
        x = alku
        alku = 1
        return x

        --------------------

        Pythonini kääntää tuon tavu koodiksi:

        --------------------

        5 0 LOAD_FAST 0 (alku)
        3 STORE_FAST 2 (x)

        6 6 SETUP_LOOP 36 (to 45)
        >> 9 LOAD_FAST 0 (alku)
        12 LOAD_FAST 1 (loppu)
        15 COMPARE_OP 0 (<)
        18 POP_JUMP_IF_FALSE 44

        7 21 LOAD_FAST 2 (x)
        24 LOAD_FAST 0 (alku)
        27 INPLACE_ADD
        28 STORE_FAST 2 (x)

        8 31 LOAD_FAST 0 (alku)
        34 LOAD_CONST 1 (1)
        37 INPLACE_ADD
        38 STORE_FAST 0 (alku)
        41 JUMP_ABSOLUTE 9
        >> 44 POP_BLOCK

        9 >> 45 LOAD_FAST 2 (x)
        48 RETURN_VALUE

        --------------------

        Tuota tavukoodia se sitten tulkitsee ajon akaisesti (C -pätkä python:n sorsasta). Lopputulos on, että yksinkertaisen Python ohjelman läpi viemiseen prosessorin pitää ajaa läpi 10-100x käskymäärä verattuna siihen jos ohjelman olisin tehnyt ohjelman Java:lla tai C:llä.

        --------------------

        ....

        switch (opcode) {

        ....

        TARGET(LOAD_FAST) {
        PyObject *value = GETLOCAL(oparg);
        if (value == NULL) {
        format_exc_check_arg(PyExc_UnboundLocalError,
        UNBOUNDLOCAL_ERROR_MSG,
        PyTuple_GetItem(co->co_varnames, oparg));
        goto error;
        }
        Py_INCREF(value);
        PUSH(value);
        FAST_DISPATCH();
        }

        PREDICTED(STORE_FAST);
        TARGET(STORE_FAST) {
        PyObject *value = POP();
        SETLOCAL(oparg, value);
        FAST_DISPATCH();
        }

        PREDICTED(STORE_FAST);
        TARGET(STORE_FAST) {
        PyObject *value = POP();
        SETLOCAL(oparg, value);
        FAST_DISPATCH();
        }

        TARGET(POP_TOP) {
        PyObject *value = POP();
        Py_DECREF(value);
        FAST_DISPATCH();
        }

        TARGET(COMPARE_OP) {
        PyObject *right = POP();
        PyObject *left = TOP();
        PyObject *res = cmp_outcome(oparg, left, right);
        Py_DECREF(left);
        Py_DECREF(right);
        SET_TOP(res);
        if (res == NULL)
        goto error;
        PREDICT(POP_JUMP_IF_FALSE);
        PREDICT(POP_JUMP_IF_TRUE);
        DISPATCH();
        }

        TARGET(INPLACE_ADD) {
        PyObject *right = POP();
        PyObject *left = TOP();
        PyObject *sum;
        if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) {
        sum = unicode_concatenate(left, right, f, next_instr);
        /* unicode_concatenate consumed the ref to left */
        }
        else {
        sum = PyNumber_InPlaceAdd(left, right);
        Py_DECREF(left);
        }
        Py_DECREF(right);
        SET_TOP(sum);
        if (sum == NULL)
        goto error;
        DISPATCH();
        }

        PREDICTED(POP_JUMP_IF_FALSE);
        TARGET(POP_JUMP_IF_FALSE) {
        PyObject *cond = POP();
        int err;
        if (cond == Py_True) {
        Py_DECREF(cond);
        FAST_DISPATCH();
        }
        if (cond == Py_False) {
        Py_DECREF(cond);
        JUMPTO(oparg);
        FAST_DISPATCH();
        }
        err = PyObject_IsTrue(cond);
        Py_DECREF(cond);
        if (err > 0)
        err = 0;
        else if (err == 0)
        JUMPTO(oparg);
        else
        goto error;
        DISPATCH();
        }

        ...

        ----


      • Tyypitön_ kirjoitti:

        Ajallisesti yksi käsky ei ehkä vie kauan, mutta kun se käskyn suoritus kestää Pythonissa 5-100x kauemmin mitä useimilla muilla kielillä, niin ero alkaakin ole melko huomatta. Laskusarjan minkä tuloksen Python suoltaa 1 tunnissa, suoltaa useammat muut kielet murto osassa kyseisestä ajasta.

        Jos teen seuraavan Python pätkän:

        --------------------

        def laske_summa(alku, loppu):
        x = alku
        while alku < loppu:
        x = alku
        alku = 1
        return x

        --------------------

        Pythonini kääntää tuon tavu koodiksi:

        --------------------

        5 0 LOAD_FAST 0 (alku)
        3 STORE_FAST 2 (x)

        6 6 SETUP_LOOP 36 (to 45)
        >> 9 LOAD_FAST 0 (alku)
        12 LOAD_FAST 1 (loppu)
        15 COMPARE_OP 0 (<)
        18 POP_JUMP_IF_FALSE 44

        7 21 LOAD_FAST 2 (x)
        24 LOAD_FAST 0 (alku)
        27 INPLACE_ADD
        28 STORE_FAST 2 (x)

        8 31 LOAD_FAST 0 (alku)
        34 LOAD_CONST 1 (1)
        37 INPLACE_ADD
        38 STORE_FAST 0 (alku)
        41 JUMP_ABSOLUTE 9
        >> 44 POP_BLOCK

        9 >> 45 LOAD_FAST 2 (x)
        48 RETURN_VALUE

        --------------------

        Tuota tavukoodia se sitten tulkitsee ajon akaisesti (C -pätkä python:n sorsasta). Lopputulos on, että yksinkertaisen Python ohjelman läpi viemiseen prosessorin pitää ajaa läpi 10-100x käskymäärä verattuna siihen jos ohjelman olisin tehnyt ohjelman Java:lla tai C:llä.

        --------------------

        ....

        switch (opcode) {

        ....

        TARGET(LOAD_FAST) {
        PyObject *value = GETLOCAL(oparg);
        if (value == NULL) {
        format_exc_check_arg(PyExc_UnboundLocalError,
        UNBOUNDLOCAL_ERROR_MSG,
        PyTuple_GetItem(co->co_varnames, oparg));
        goto error;
        }
        Py_INCREF(value);
        PUSH(value);
        FAST_DISPATCH();
        }

        PREDICTED(STORE_FAST);
        TARGET(STORE_FAST) {
        PyObject *value = POP();
        SETLOCAL(oparg, value);
        FAST_DISPATCH();
        }

        PREDICTED(STORE_FAST);
        TARGET(STORE_FAST) {
        PyObject *value = POP();
        SETLOCAL(oparg, value);
        FAST_DISPATCH();
        }

        TARGET(POP_TOP) {
        PyObject *value = POP();
        Py_DECREF(value);
        FAST_DISPATCH();
        }

        TARGET(COMPARE_OP) {
        PyObject *right = POP();
        PyObject *left = TOP();
        PyObject *res = cmp_outcome(oparg, left, right);
        Py_DECREF(left);
        Py_DECREF(right);
        SET_TOP(res);
        if (res == NULL)
        goto error;
        PREDICT(POP_JUMP_IF_FALSE);
        PREDICT(POP_JUMP_IF_TRUE);
        DISPATCH();
        }

        TARGET(INPLACE_ADD) {
        PyObject *right = POP();
        PyObject *left = TOP();
        PyObject *sum;
        if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) {
        sum = unicode_concatenate(left, right, f, next_instr);
        /* unicode_concatenate consumed the ref to left */
        }
        else {
        sum = PyNumber_InPlaceAdd(left, right);
        Py_DECREF(left);
        }
        Py_DECREF(right);
        SET_TOP(sum);
        if (sum == NULL)
        goto error;
        DISPATCH();
        }

        PREDICTED(POP_JUMP_IF_FALSE);
        TARGET(POP_JUMP_IF_FALSE) {
        PyObject *cond = POP();
        int err;
        if (cond == Py_True) {
        Py_DECREF(cond);
        FAST_DISPATCH();
        }
        if (cond == Py_False) {
        Py_DECREF(cond);
        JUMPTO(oparg);
        FAST_DISPATCH();
        }
        err = PyObject_IsTrue(cond);
        Py_DECREF(cond);
        if (err > 0)
        err = 0;
        else if (err == 0)
        JUMPTO(oparg);
        else
        goto error;
        DISPATCH();
        }

        ...

        ----

        "Ajallisesti yksi käsky ei ehkä vie kauan, mutta kun se käskyn suoritus kestää Pythonissa 5-100x kauemmin mitä useimilla muilla kielillä, niin ero alkaakin ole melko huomatta."

        100x vaikuttaa siltä, että koodissa on jotain pielessä.

        "Jos teen seuraavan Python pätkän:"

        Kirjoittamasi koodi on pielessä.

        Pitäisi olla:

        'def laske_summa(alku, loppu):
        ' return sum(range(alku, loppu)) alku

        Useimmissa ohjelmissa voi olla funktion kirjoittaminen tuohon ylimitoitettua jos ei ole toistoa.

        "Lopputulos on, että yksinkertaisen Python ohjelman läpi viemiseen prosessorin pitää ajaa läpi 10-100x käskymäärä verattuna siihen jos ohjelman olisin tehnyt ohjelman Java:lla tai C:llä."

        Sillä käskymäärälläkään ei ole oikein merkitystä. Se homma kun menee niin, että aina kun tarvitsee siirtyä rekistereistä L1 cache, L2 cache, L3 cache, ram, levy/verkko cache, kiintolevy, verkko jne. niin aina hyytyy rajusti.

        Käytännössä koodissa voi yleensä olla valtavat määrät käskyjä kun nopeuden määrää se toimitaanko millä tasolla muistipyramidissa. Viivettä tulee siitäkin kun käynnistää vaikka prosessin tai säikeen. Tarpeeksi lyhkäisistä ajoista kun on kyse niin niillä ei ole oikein väliä.

        Laitoin tuossa laske_summa -funktiossa arvot 1000 ja 100000 ja oli niin nopea, että ei siinä tuntia mennyt vaan muutama millisekunti.


      • M-Kar kirjoitti:

        "Ajallisesti yksi käsky ei ehkä vie kauan, mutta kun se käskyn suoritus kestää Pythonissa 5-100x kauemmin mitä useimilla muilla kielillä, niin ero alkaakin ole melko huomatta."

        100x vaikuttaa siltä, että koodissa on jotain pielessä.

        "Jos teen seuraavan Python pätkän:"

        Kirjoittamasi koodi on pielessä.

        Pitäisi olla:

        'def laske_summa(alku, loppu):
        ' return sum(range(alku, loppu)) alku

        Useimmissa ohjelmissa voi olla funktion kirjoittaminen tuohon ylimitoitettua jos ei ole toistoa.

        "Lopputulos on, että yksinkertaisen Python ohjelman läpi viemiseen prosessorin pitää ajaa läpi 10-100x käskymäärä verattuna siihen jos ohjelman olisin tehnyt ohjelman Java:lla tai C:llä."

        Sillä käskymäärälläkään ei ole oikein merkitystä. Se homma kun menee niin, että aina kun tarvitsee siirtyä rekistereistä L1 cache, L2 cache, L3 cache, ram, levy/verkko cache, kiintolevy, verkko jne. niin aina hyytyy rajusti.

        Käytännössä koodissa voi yleensä olla valtavat määrät käskyjä kun nopeuden määrää se toimitaanko millä tasolla muistipyramidissa. Viivettä tulee siitäkin kun käynnistää vaikka prosessin tai säikeen. Tarpeeksi lyhkäisistä ajoista kun on kyse niin niillä ei ole oikein väliä.

        Laitoin tuossa laske_summa -funktiossa arvot 1000 ja 100000 ja oli niin nopea, että ei siinä tuntia mennyt vaan muutama millisekunti.

        Voisi olla hauskaa kokeilla onko kuinka paljon käytännön eroa ja mihin jossain todellisessa ongelmassa kun käyttää Pythonia verrattuna joku muu työkalu.

        Semmoinen rajaus varmaan olisi hyvä tehdä, että jättää fronttijutut pois kun niihin on ihan omat työkalunsa. Eli miten "hidas" se nyt sitten olisi backendissä, unix skriptauksessa tai jossain yleisessä tietojenkäsittelytehtävässä.


      • Tyypitön_

        Laitoin sen "pielessä" olevan koodin ajoon arvoilla (0,1000000000) niin Python tahkoi tulosta liki 180s, ja tuolla sun koodin avulla aika tippui 70s:ään. Se on kuitenkin tolkuttoman hidasta, kun jopa Javalla tehty vastaava ohjelma sylkäisi vastaavan laskun tuloksen ruudulle alle 2s. Jopa PHP meni Pythonin edelle 30s suoritus ajalla.

        --- JAVA ---

        public static long laske_summa(long alku, long loppu) {
        long x = alku;
        while(alku < loppu) {
        x = alku;
        alku ;
        }
        return x;
        }

        --- PHP ---

        function laske_summa($alku, $loppu) {
        $x = $alku;
        while($alku < $loppu) {
        $x = $alku;
        $alku ;
        }
        return $x;
        }

        10x käskyn suoritus vie 10x ajan kuin 1 käskyn, ja 100x käskyä vie 100x ajan kuin 1 käskyn.... Itse Pythonin suoritus kyky on varsin surkea, (nopeutta saa vain käyttämällä tai pykäämällä C:llä kirjoiteun moduulin joka hoitaa varsinaisen laskennan)...


      • Tyypitön_
        M-Kar kirjoitti:

        Voisi olla hauskaa kokeilla onko kuinka paljon käytännön eroa ja mihin jossain todellisessa ongelmassa kun käyttää Pythonia verrattuna joku muu työkalu.

        Semmoinen rajaus varmaan olisi hyvä tehdä, että jättää fronttijutut pois kun niihin on ihan omat työkalunsa. Eli miten "hidas" se nyt sitten olisi backendissä, unix skriptauksessa tai jossain yleisessä tietojenkäsittelytehtävässä.

        Tietojenkäsittelytehtävä voisi olla vaikka pakata, kryptata, laskea hajautus arvo, tms. jostakin 32 Gt tiedostossa. Jos ihan pelkstään jos XOR:a kaikki tiedoston tavut ykkösellä, niin tulosero on aivan selvä.

        Tiedoston koko 120 Mt:

        Python 20s
        Java <2s

        Tiedoston koko 840 Mt:

        Python 140s
        Java 5s


        En edes jaksa kokeilla 32 Gt:lla, kun tuosta voi laskea että Javalla se menee n. 3 min ja Pythonilla n. 89 min. Pythonista ei saa laskennassa nopaa kuin käyttämällä C:llä tehtyjä moduuleita. Aina sitä voi sanoa että koodissa on vikaa, mutta se nyt vaan on niin itse Pythonin suoritus kyky on heikko...

        --- JAVA ---

        public static void salaa(String tiedosto_in, String tiedoto_out) {
        try (
        InputStream sisään = new FileInputStream(tiedosto_in);
        OutputStream ulos = new FileOutputStream(tiedoto_out);
        ) {
        byte[] tavut = new byte[1024*1024];

        while(true) {
        int pituus = sisään.read(tavut);

        if (pituus <= 0)
        break;

        for (int i = 0; i < pituus; i )
        tavut[i] ^= 0x01;

        ulos.write(tavut, 0, pituus);
        }


        } catch (IOException ex) {
        ex.printStackTrace();
        }
        }

        --- PYTHON ---

        def salaa(tiedosto_in, tiedosto_out):
        with open(tiedosto_in, "rb") as f_src, open(tiedosto_out, "wb") as f_dst:
        while True:
        tavut = bytearray(f_src.read(1024*1024))
        pituus = len(tavut)
        if pituus == 0:
        break
        for i in range(pituus):
        tavut[i] ^= 0x01
        f_dst.write(tavut)


      • Tyypitön_ kirjoitti:

        Tietojenkäsittelytehtävä voisi olla vaikka pakata, kryptata, laskea hajautus arvo, tms. jostakin 32 Gt tiedostossa. Jos ihan pelkstään jos XOR:a kaikki tiedoston tavut ykkösellä, niin tulosero on aivan selvä.

        Tiedoston koko 120 Mt:

        Python 20s
        Java <2s

        Tiedoston koko 840 Mt:

        Python 140s
        Java 5s


        En edes jaksa kokeilla 32 Gt:lla, kun tuosta voi laskea että Javalla se menee n. 3 min ja Pythonilla n. 89 min. Pythonista ei saa laskennassa nopaa kuin käyttämällä C:llä tehtyjä moduuleita. Aina sitä voi sanoa että koodissa on vikaa, mutta se nyt vaan on niin itse Pythonin suoritus kyky on heikko...

        --- JAVA ---

        public static void salaa(String tiedosto_in, String tiedoto_out) {
        try (
        InputStream sisään = new FileInputStream(tiedosto_in);
        OutputStream ulos = new FileOutputStream(tiedoto_out);
        ) {
        byte[] tavut = new byte[1024*1024];

        while(true) {
        int pituus = sisään.read(tavut);

        if (pituus <= 0)
        break;

        for (int i = 0; i < pituus; i )
        tavut[i] ^= 0x01;

        ulos.write(tavut, 0, pituus);
        }


        } catch (IOException ex) {
        ex.printStackTrace();
        }
        }

        --- PYTHON ---

        def salaa(tiedosto_in, tiedosto_out):
        with open(tiedosto_in, "rb") as f_src, open(tiedosto_out, "wb") as f_dst:
        while True:
        tavut = bytearray(f_src.read(1024*1024))
        pituus = len(tavut)
        if pituus == 0:
        break
        for i in range(pituus):
        tavut[i] ^= 0x01
        f_dst.write(tavut)

        "Laitoin sen "pielessä" olevan koodin ajoon arvoilla (0,1000000000) niin Python tahkoi tulosta liki 180s, ja tuolla sun koodin avulla aika tippui 70s:ään. Se on kuitenkin tolkuttoman hidasta, kun jopa Javalla tehty vastaava ohjelma sylkäisi vastaavan laskun tuloksen ruudulle alle 2s."

        No jos noin valtavia listoja tehdään niin ilmeinen yhden merkin muutos python 2.x koodiin olisi tämä:

        'def laske_summa(alku, loppu):
        ' return sum(xrange(alku, loppu)) alku

        Sitä kun range palauttaa listan ja xrange olisi sitten lazy evaluationia ja palauttaa evaluoi siinä kohtaa kun tarvitaan. Ei tule sitten Pyhonille tässäkään mitään yli 10x eroja.

        "Tietojenkäsittelytehtävä voisi olla vaikka pakata, kryptata, laskea hajautus arvo, tms. jostakin 32 Gt tiedostossa. Jos ihan pelkstään jos XOR:a kaikki tiedoston tavut ykkösellä, niin tulosero on aivan selvä."

        No ei. 32Gt jos on vaikka kiintolevyllä joka rallattaa esim. 50Mt/s niin hidastetta tulee jo siitätiedonsiirtonopeudesta, että aikaa menee noin 11min pelkästään kun dataa luetaan. Toinen 11min menee kirjoitukseen. Sitten voi vielä arvioida, että on joku millisekunnin latenssi aina kun luetaan pala dataa tai kirjoitetaan. Se että kellotit nopeita suoritusaikoja varmaan meinaa sitä, että data tuli sinulla cachesta vaikka mutta kyllä se Java hyytyy tasan tarkkaan siihen mitä IO:sta lähtee mikä kaventaa rajusti sitä todellista suorituskykyeroa.

        Tuollaisessa Python koodissa tehtävässä laskennassa voi tuollaisilla määrillä iterointeja aikaa kyllä jo mennä mutta erot eivät ole niin järisyttäviä kun siellä tekee IO jarrua.

        Ja näinhän se ohjelmoinnissa yleensä onkin, että suorituskykyjarrut tulee verkosta ja IO:sta, ja normaalisti prosessointia ei tarvitse edes huomioida kun se tapahtuu "heti". Jos nyt ihan oikeasti on tarkoitus käyttää laskimena ja valtavilla datamäärillä niin se on ihan oma erikoiskeissi sitten. On ihan tavallista, että laskinklustereissa ei ajeta muita kuin natiiviksi käännettyjä ohjelmia, että Javat ja Python VM:t ei sinne kuulu.

        Tyypillisempi, reaalimaailman esimerkki olisi ollut vaikka se, että tehtään HTTP query joka palauttaa vaikka jostain datasetistä jollain hakuehdolla jsonina dataa.


      • Tyypitön_ kirjoitti:

        Tietojenkäsittelytehtävä voisi olla vaikka pakata, kryptata, laskea hajautus arvo, tms. jostakin 32 Gt tiedostossa. Jos ihan pelkstään jos XOR:a kaikki tiedoston tavut ykkösellä, niin tulosero on aivan selvä.

        Tiedoston koko 120 Mt:

        Python 20s
        Java <2s

        Tiedoston koko 840 Mt:

        Python 140s
        Java 5s


        En edes jaksa kokeilla 32 Gt:lla, kun tuosta voi laskea että Javalla se menee n. 3 min ja Pythonilla n. 89 min. Pythonista ei saa laskennassa nopaa kuin käyttämällä C:llä tehtyjä moduuleita. Aina sitä voi sanoa että koodissa on vikaa, mutta se nyt vaan on niin itse Pythonin suoritus kyky on heikko...

        --- JAVA ---

        public static void salaa(String tiedosto_in, String tiedoto_out) {
        try (
        InputStream sisään = new FileInputStream(tiedosto_in);
        OutputStream ulos = new FileOutputStream(tiedoto_out);
        ) {
        byte[] tavut = new byte[1024*1024];

        while(true) {
        int pituus = sisään.read(tavut);

        if (pituus <= 0)
        break;

        for (int i = 0; i < pituus; i )
        tavut[i] ^= 0x01;

        ulos.write(tavut, 0, pituus);
        }


        } catch (IOException ex) {
        ex.printStackTrace();
        }
        }

        --- PYTHON ---

        def salaa(tiedosto_in, tiedosto_out):
        with open(tiedosto_in, "rb") as f_src, open(tiedosto_out, "wb") as f_dst:
        while True:
        tavut = bytearray(f_src.read(1024*1024))
        pituus = len(tavut)
        if pituus == 0:
        break
        for i in range(pituus):
        tavut[i] ^= 0x01
        f_dst.write(tavut)

        Noin lyhyesti, jos ei ole mitään älyttömiä määriä iterointeja niin erot prosessoinnissa on olemattomat. Aina kun käskee suorittamaan niin tapahtuu alle sekunnissa. Vasta suuremmilla määrillä iteraatioita alkoi tulla eroa.

        Ja mitä nyt testannut kahdella, melkoisen synteettisellä testillä joista toinen IO riippuvainen, näyttäisi suoritusaika olevan Javaan nähden noin 4x heikompaa ja ero näkyy kun iterointeja on valtavasti.

        Lähinnä tuo voi näkyä suuremmilla kuormilla palvelinkustannuksissa jos prosessoitavat asiat ovat kovin paljon CPU:sta riippuvaisia. Yleensä ovat kyllä kannasta.

        Sitten jos lokaalisti jotain tekee niin alle sekunnin suoritusajat ovat yks hailee. Seuraava rajapyykki on 10s, tästä seuraava kahvi/tupakkitauko, lounastauko, yön yli, viikonlopun aikana...

        Ainahan se on plussaa kun saa optimoitua pykälää nopeammaksi seuraavaan aikaluokkaan, ja yleensä alle 10x erot ovat mitättömiä kun ne menevät siinä samassa aikaluokassa. Algoritmitason parannukset merkitsevät käytännössä aina eniten.


    • 102030405060

      Windowsissa kun ajaa pythonia WSL:n kautta, niin nopeus parani huomattavasti.

      Ei sillä, että suorituskyky olisi ollut ongelma ennenkään, mutta mielenkiintoinen juttu . . .

    • geqrgwegwer
    • Python-on-OK

      Python on todella nopea silmukoissaan. Yli 2 kertaa nopeampi kuin C

      Tässä muutama todellinen nopeustesti While silmukalla, kun Python koodia ajetaan eri tulkin vauhdittamana. Ja sama While silmukka C kielellä.

      testi1.py koodi tässä
      -------------------------------------------------------------------------------------------------------------
      import time
      import sys

      l=1000000000
      a=0
      start = time.time()
      while (a < l):
      a = a 1
      print (time.time()-start)
      -------------------------------------------------------------------------------------------------------------

      Ajat eri tulkin vauhdittamana
      - pypy test1.py = 0.872668981552 Sekuntia
      - python test1.py = 54.5364089012 Sekuntia
      - python3 test1.py = 78.98015880584717 Sekuntia

      Tässä ihmetyttää se että Python omilla sivuillaan kehuu suorituskyvyn parantuvan entisestään jokaisen uuden version myötä, mutta käytännön testi osoittaa sen koko ajan vain hidastuvan.

      - C = 2.205191 Sekuntia

      Tästä syystä voidaan sanoa että Python koodi on yli kaksi kertaa nopeampaa kuin vastaava C koodi, ainakin tässä While silmukassa. Formula 1 -auto on yksipaikkainen Formula 1 -sarjassa käytettävä kilpa-auto, ja sillä on todella hankala rahdata tukkilasteja rajan takaa. Eli kieli ja kääntäjä tarpeen mukaan.

      Linux Mint 18 Sarah
      Xfce 64-bit

      • Pythonia ei yleensä ohjelmoida noin.

        Se suorituskyvyn parantuminen vaikuttaa siihen kun Pythonia ohjelmoidaan normaaliin tapaan enemmän funktionaalisesti. Sinne on lisätty optimointeja tätä varten.


    Ketjusta on poistettu 4 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. KUPSinpelaaja vangittu törkeästä rikoksesta

      Tänään tuli uutinen että Kupsin sopimuspelaajs vangittu törkeästä rikoksesta epäiltynä. Kuka pelaaja kysressä ja mikä ri
      Kuopio
      18
      1475
    2. Taasko se show alkaa

      Koo osottaa taas mieltään
      Ikävä
      28
      1305
    3. Minun oma kaivattuni

      Ei ole mikään ilkeä kiusaajatyyppi, vaan sivistynyt ja fiksu sekä ystävällinen ihminen, ja arvostan häntä suuresti. Raka
      Ikävä
      63
      1202
    4. Miksi ihmeessä nainen seurustelit kanssani joskus

      Olin ruma silloin ja nykyisin vielä rumempi En voi kuin miettiä että miksi Olitko vain rikki edellisestä suhteesta ja ha
      Ikävä
      11
      1092
    5. Tervehdys!

      Sä voit poistaa nää kaikki, mut mä kysyn silti A:lta sen kokemuksia sun käytöksestä eron jälkeen. Btw, miks haluut sabot
      Turku
      65
      1036
    6. Onko ministeri Juuso epäkelpo ministerin tehtäviensä hoitamiseen?

      Eikö hänellä ole kompetenttia hoitaa sosiaali- ja terveysministetin toimialalle kuuluvia ministerin tehtäviä?
      Perussuomalaiset
      10
      1026
    7. Persut nimittivät kummeli-hahmon valtiosihteeriksi!

      Persujen riveistä löytyi taas uusi törkyturpa valtiosihteeriksi! Jutun perusteella järjenjuoksu on kuin sketsihahmolla.
      Perussuomalaiset
      27
      1025
    8. Elia tulee vielä

      Johannes Kastaja oli Elia, mutta Jeesus sanoi, että Elia tulee vielä. Malakian kirjan profetia Eliasta toteutuu kokonaan
      Helluntailaisuus
      30
      989
    9. Sakarjan kirjan 6. luku

      Jolla korva on, se kuulkoon. Sain profetian 22.4.2023. Sen sisältö oli seuraava: Suomeen tulee nälänhätä niin, että se
      Profetiat
      6
      981
    10. Kaupungin valtuuston yleisötilaisuus

      YouTubessa katsojia 76 Buahahaha buahahaha buahahaha buahahaha buahahaha buahahaha
      Varkaus
      1
      980
    Aihe