Kirjoittaja Aihe: Nopeuskisa: Perl vastaan Python – voiko olla totta?  (Luettu 10979 kertaa)

odysseus

  • Vieras
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #20 : 19.05.12 - klo:15.33 »
Hauska testi tosiaan.

Tässä on pari mielenkiintoista dilemmaa. Ihan ensiksi, koko ongelma (ja alkuperäinen kysymys) oli, että mikä "ohjelmointi"kieli on nopeampi ja ongelman määrittely oli metakielellä:

-luetaan tiedosto(a) levyltä
-tehdään hae-korvaa-toiminto määrätyillä kriteereillä
-tallenetaan lopputulos toisen tiedostoon

Tässä ongelman määrittelyssä ei siis pitäisi välittää siitä, onko jossain kielessä "säännöllisiä lausekkeita" vai ei. Tavoite oli tuottaa kyseisellä ohjelmointikielellä ja sen keinoilla _mahdollisimman nopea_ lopputulos. Jos ohjelmointikieli sallii nopeimman tavan, niin se siis sallittakoon.

Tuo C-kielinen pätkä lähentelee hyvää prototyyppiä "find-search"-toiminnosta, josta voidaan todeta, että olisi typerää lukea data ensin puskuriin (varata muistia) ja sitten alkaa korvaamaan sitä merkki kerrallaan, varsinkin kun muutettava merkki muutetaan pidemmäksi (tai lyhyemmäksi) merkkijonoksi (ja taas tarvittaessa varata muistia) jne...
C:n edut ja osoittimien käsittely tulee hyvin ilmi tässä kun ei tarvitse jokaisen osuman kohdalla kopioida loppubufferia eteenpäin korvattavien merkkien määrällä jne... Pukataan vain dataa raakana eteenpäin ja sillä siisti.

Tuossa protossa on kuitenkin (juuri) se (aavistelemani) vika, että se tukee vain "sizeof(char)" kokoa, joten unicode ei mene suoraan ja muut kuin ASCII mättää. Tuo voidaan tietty korvata fread ja fwrite -funktioilla, jolloin voidaan määrittää "character-encoding":n määräämä bittiluku.
Tunnustelemalla sen ja antamalla nuo syötteet parametrina, se on aika valmis find-replace-toiminto. Muutos tarvitaan vain kohtaan, misssä putc:t ovat jos osuma tulee. Siihen tarvitaan toinen looppi, joka katsoo korvattavan merkin pituuden.

Kokonaisuutena tämä oli erinomainen esimerkki siitä, että jokaisen ohjelmoijan kannatta(a/isi) miettiä miten tuollaisa aikaavieviä juttuja koodataan ja millä kielellä. Joskus on viisasta tehdä C:llä sopiva pikku funktio (="kirjasto", jonka tarvittavat funktiot on exportattu), jota sitten kutsutaan tarvittaessa toisista kielistä.
Sen päätöksen tekemiseen vaikuttavat businessprojekteissa ainakin seuraavat:

-käännetyn ohjelman suoritusaika (lopputuotteen nopeus)
-lähdekielen kirjoittamisen nopeus (RAD development)
-lähdekielen ylläpidettävyys (riskien hallinta varsinkin jos kieli on standardoimaton ja "tuntematon")
-lähdekielen laitteisto/alustariippumattomuus (toimii "kaikissa": Win, Linux, Mac, Unix...)
-käännetyn ohjelman sijoitus (voiko/onko oikeuksia laittaa se palvelimelle (esimerkiksi nettipalvelimelle))

Ja muistettakoon, että optimoida voi loputtomiin, mutta normitilanteessa (ainakin C) kääntäjä kyllä pääsääntöisesti optimoi nopeuden ja koodin koon paremmin kuin itse tehty ASM.

Tomin

  • Palvelimen ylläpitäjä
  • Käyttäjä / moderaattori+
  • Viestejä: 11442
    • Profiili
    • Tomin kotisivut
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #21 : 19.05.12 - klo:15.36 »
Täältä löytyy Java lähdekoodi + datafile mitä käytin: http://corei7.no-ip.biz/~petria/replaceTest/
Kannattanee pakata tuo datafile. :)

Pitänee itsekin kokeilla, pitää vaan jaksaa kirjoitella sopiva skripti tiedostoa varten.

Muokkaus: Pieni python satunnaisgeneraattori testailijoille tulostaa tavaran stdoutiin. Tekee 100 riviä (muuttujana, haluat ehkä vaihtaa vielä isommaksi) 1-80 merkkiä pitkiä rivejä a-kirjainta. Yksinkertaisuuden nimissä ohjelma ei ota mitään parametreja. Public domainia, ei tuossa kyllä mitään kovin kummosta koodia olekaan.
Pakkasin gzipillä, kun ei hyväksynyt py päätettä, purkaminen yksinkertaisesti: gunzip satunnaisdataa.py.gz
Suoritus (chmodauksen jälkeen): ./satunnaisdataa.py > data.txt
« Viimeksi muokattu: 19.05.12 - klo:17.28 kirjoittanut Tomin »
Automaattinen allekirjoitus:
Lisäisitkö [RATKAISTU] ketjun ensimmäisen viestin aiheeseen ongelman ratkettua, kiitos.

SuperOscar

  • Käyttäjä
  • Viestejä: 4000
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #22 : 19.05.12 - klo:15.59 »
Tässä on pari mielenkiintoista dilemmaa. Ihan ensiksi, koko ongelma (ja alkuperäinen kysymys) oli, että mikä "ohjelmointi"kieli on nopeampi ja ongelman määrittely oli metakielellä:

-luetaan tiedosto(a) levyltä
-tehdään hae-korvaa-toiminto määrätyillä kriteereillä
-tallenetaan lopputulos toisen tiedostoon

Oikeastaan varsinainen kiistakapulamme oli ainoastaan keskimmäinen kohta eli itse datan käsittely, eivät I/O-operaatiot. On vain vaikea tehdä testiä skriptin ulkopuolelta (time-komennolla) niin, ettei vähintään ensimmäinen vaihe tule mukaan laskuun.

Lainaus
Tässä ongelman määrittelyssä ei siis pitäisi välittää siitä, onko jossain kielessä "säännöllisiä lausekkeita" vai ei.

Sinun määrittelyssäsi ei, mutta meidän kiistassamme kyse oli ensi sijassa siitä, mikä kieli on nopein, kun säännöllisin lausekkein täytyy isoja datatiedostoja muuntaa palvelimella web-käyttöliittymää varten.

Säännölliset lausekkeet ovat niin keskeinen osa Perlin perussyntaksia, että itsekin uskoin aluksi Perlin selviävän voittajaksi, joskin toivoin, ettei Python häviäisi kovin paljon. Tämä tulos ON minulle yllätys.

Muoks: Voittajasta ei vielä tiedä, mutta häviäjä löytyi :-\ Kokeilin D:tä, ja tulos oli masentava. 40-megainen tiedosto siirtyi Pythonilta /dev/nulliin nyt 17,29 sekunnissa, mutta käännetty D-ohjelma vei yli kymmenkertaisesti aikaa, 185,50 s. Jatkuvat tyypinvaihdot varmaankin kestävät, mutta D on vähän omituinen: joskus funktio ottaa argumentin char[], joskus argumentin string. Koodi tässä:

Koodia: [Valitse]
// test.d

import std.stdio;
import std.regex;

void main()
{
    auto pattern = regex(r"a", "g");
    string line_out;

    foreach (line; stdin.byLine) {
        line_out = cast(string) line;
        foreach (m; match(line, pattern))
            line_out = replace(line_out, pattern, "ööön");
        writeln(line_out);
    }
}
« Viimeksi muokattu: 19.05.12 - klo:17.22 kirjoittanut SuperOscar »
pöytäkone 1, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; NUC: openSUSE Leap 15.5; RPi 1: FreeBSD 14-RELEASE; RPi 2: LibreELEC 11

_Pete_

  • Käyttäjä
  • Viestejä: 1836
  • Fufufuuffuuu
    • Profiili
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #23 : 20.05.12 - klo:10.31 »
Pitipä virkistää C-taitoja ja sain kuin sainkin toimivan C-version aikaiseksi käyttäen hyväkseen glib,
se testin mukaan tosin on hitaampi kuin python-versio:

C
Koodia: [Valitse]
$ time ./a.out <datafile.txt  >/dev/null

real 0m8.668s
user 0m8.613s
sys 0m0.036s

Koodi ja datafile.txt on täällä: http://corei7.no-ip.biz/~petria/replaceTest/

« Viimeksi muokattu: 20.05.12 - klo:10.39 kirjoittanut _Pete_ »

odysseus

  • Vieras
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #24 : 20.05.12 - klo:12.27 »
Pitipä virkistää C-taitoja ja sain kuin sainkin toimivan C-version aikaiseksi käyttäen hyväkseen glib,
se testin mukaan tosin on hitaampi kuin python-versio:

Hitauden syy on GRegex:n käyttö, joka on huono tähän toimenpiteeseen. Miksi ihmeessä teit sen noin?


odysseus

  • Vieras
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #25 : 20.05.12 - klo:12.32 »
Lainaus
Tässä ongelman määrittelyssä ei siis pitäisi välittää siitä, onko jossain kielessä "säännöllisiä lausekkeita" vai ei.

Sinun määrittelyssäsi ei, mutta meidän kiistassamme kyse oli ensi sijassa siitä, mikä kieli on nopein, kun säännöllisin lausekkein täytyy isoja datatiedostoja muuntaa palvelimella web-käyttöliittymää varten.

Lueppa uudelleen aloituksesi. Ketjun ensimmäisessä viestissä ei millään muotoa sanota, että ongelman määrittelyyn liittyisi säännölliset lausekkeet tai web-käyttöliittymä! Asia tuodaan lisäyksenä esiin vasta myöhemmissä kirjoituksissa.

Siispä minun määrittelyni on juuri sellainen millasesta ongelmasta alunperin oli kyse.

_Pete_

  • Käyttäjä
  • Viestejä: 1836
  • Fufufuuffuuu
    • Profiili
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #26 : 20.05.12 - klo:12.41 »
Pitipä virkistää C-taitoja ja sain kuin sainkin toimivan C-version aikaiseksi käyttäen hyväkseen glib,
se testin mukaan tosin on hitaampi kuin python-versio:

Hitauden syy on GRegex:n käyttö, joka on huono tähän toimenpiteeseen. Miksi ihmeessä teit sen noin?

Koska se nyt oli ainut järkevän helposti käytettävä toteutus C:llä regex:stä, joka siis alkuperäisessä tehtävässä oli tarkoitus olla käytössä.

SuperOscar

  • Käyttäjä
  • Viestejä: 4000
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #27 : 20.05.12 - klo:13.57 »
Lueppa uudelleen aloituksesi. Ketjun ensimmäisessä viestissä ei millään muotoa sanota, että ongelman määrittelyyn liittyisi säännölliset lausekkeet tai web-käyttöliittymä! Asia tuodaan lisäyksenä esiin vasta myöhemmissä kirjoituksissa.

No anteeksi nyt kauheasti ::) Ovat ne silti oleellisia sen kiistan kannalta, mitä nyt yritetään ratkoa.
pöytäkone 1, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; NUC: openSUSE Leap 15.5; RPi 1: FreeBSD 14-RELEASE; RPi 2: LibreELEC 11

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #28 : 21.05.12 - klo:11.58 »
Kysyn tässä ketjussa kun kysymys ei ansaitse omaa ketjua: onko Pythonille, Perlille ja niiden kaltaisille tehty kehitysympäristöä(siis jonkunsortin IDE)?

matsukan

  • Käyttäjä
  • Viestejä: 2148
    • Profiili
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #29 : 21.05.12 - klo:12.24 »
Google ?     Muokattu: Ei henkilökohtaisuuksia  tai ilkeilyä - ajaaskel

Esim hakusanalla Perl IDE löytyy kaksi hyvää vaihtoehtoa, Padre ja eclipse terästettynä perl lisukkeilla, http://www.epic-ide.org/.

Sitten vain vaihtamaan Perl hakusananai mieleisesi ohjelmointikielen nimellä.

Joo ei löydy helposti.
« Viimeksi muokattu: 22.05.12 - klo:12.01 kirjoittanut ajaaskel »
Pohjois-pohjanmaa
-- motto:  backupin tarve huomataan aina liian myöhään

SuperOscar

  • Käyttäjä
  • Viestejä: 4000
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #30 : 22.05.12 - klo:10.05 »
Kaverikin jo myönsi itse kokeiltuaan Pythonin Perliä nopeammaksi, joten sikäli kisa on ratkennut. Minua vielä hotsittaisi kokeilla juttua jollain funktionaalisella kielellä (Scheme? Ocaml? Haskell? Erlang?).
pöytäkone 1, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; NUC: openSUSE Leap 15.5; RPi 1: FreeBSD 14-RELEASE; RPi 2: LibreELEC 11

_Pete_

  • Käyttäjä
  • Viestejä: 1836
  • Fufufuuffuuu
    • Profiili
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #31 : 22.05.12 - klo:11.22 »
Summarum vielä omat testit, käytin isompaa datatiedostoa sekä päivitin Java version lukemaan stdin +
lisäksi vielä ruby mukaan:

Koodia: [Valitse]
$ time ./test.py <datafile_large.txt >/dev/null

real    1m19.130s
user    1m18.569s
sys     0m0.396s


$ time ./test <datafile_large.txt >/dev/null

real    1m39.137s
user    1m38.066s
sys     0m0.840s

$ time java -cp build/ ReplaceTest <datafile_large.txt >/dev/null

real    1m45.373s
user    1m43.502s
sys     0m4.296s

$ time ./test.pe <datafile_large.txt >/dev/null

real    2m54.138s
user    2m52.763s
sys     0m0.964s


$ time ./test.rb <datafile_large.txt >/dev/null

real    4m2.874s
user    3m59.259s
sys     0m2.848s


Lähdekoodit + datafileet: http://corei7.serveirc.com/~petria/replaceTest/

snifi

  • Vieras
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #32 : 22.05.12 - klo:14.41 »
Asia joka on syytä pitää mielessä: Pythonin säännölliset lausekkeet on ohjelmoitu C:llä. Jos tehtävänä on ohjelmoida jotakin säännöllisten lausekkeiden kaltaista, joka ei ole säännöllisiä lausekkeita, niin silloin Python ei ehkä ole mielekäs työkalu tehtävään.

SuperOscar

  • Käyttäjä
  • Viestejä: 4000
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #33 : 23.05.12 - klo:16.20 »
Pascalia ei ollut vielä kokeiltukaan, joten vertailutulos Python vs. Free Pascal. 396-megainen koetiedosto.

Koodia: [Valitse]
tommin@wittgenstein [~/Tilap]$ time ./test.py < aaa.dat > /dev/null
./test.py < aaa.dat > /dev/null  176,85s user 1,66s system 99% cpu 2:58,90 total
tommin@wittgenstein [~/Tilap]$ time ./test < aaa.dat > /dev/null
./test < aaa.dat > /dev/null  106,21s user 186,55s system 99% cpu 4:54,28 total

Eli Pythonilta muutostyö vei 3 min, käännetyltä Pascal-ohjelmalta 5 min.

Kone oli nyt kotikonetta hitaampi työkone (Pentium 4 2,80 GHz, kiintolevy 80 Gt Maxtor), joten tulokset ovat vertailukelpoisia vain keskenään.

Pascal-ohjelma oli tällainen:

Koodia: [Valitse]
{ test.pas }

program test;

uses sysutils,
      regexpr;

var line, newLine : AnsiString;
    pattern : tregexprengine;

begin
    if GenerateRegExprEngine('a', [], pattern) then begin
        while not eof(input) do begin
            readln(line);
            RegExprReplaceAll(pattern, line, 'ööön', newLine);
            writeln(newLine)
        end
    end
end.
pöytäkone 1, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; NUC: openSUSE Leap 15.5; RPi 1: FreeBSD 14-RELEASE; RPi 2: LibreELEC 11

Tommi S.

  • Käyttäjä
  • Viestejä: 240
    • Profiili
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #34 : 23.05.12 - klo:18.06 »
Noiden regexpien käyttäminen ei välttämättä tuo ilmi koko totuutta. Python skriptin alussa on "import re", mikä siis tarkoittaa että ladataan lisäpalikka joka on itsessään kirjoitettu C:llä, eli tässä todennäköisesti verrataan Perlin ja Pythonin regexp toteutuksia keskenään, jotka molemmat on tod.näk. konepellin alla kirjoitettu C:llä.

Lisäksi noissa regexp toteutuksissa voi ehkä olla erilaisia optimointeja, joten tällainen "korvaa yksi merkki merkkijonolla" saattaa antaa ihan eri tuloksia kuin esim. "etsi oikeanmuotoinen sosiaaliturvatunnus kirjainmoskan seasta".

Tässä omat testiskriptini jotka ottavat numeron ja jakavat sen tekijöihin. Yritin tehdä koodit mahdollisimman identtisiksi molemmissa. Jos joku tietää optimointeja niin niitä saa ehdottaa.
Tässä mitataan siis raakaa laskentaa ja kielen perusominaisuuksia, jakolaskujen nopeutta, yksittäisten käskyjen suoritusnopeutta, silmukoiden nopeutta, jne.

Omalla koneellani Python3 versio vie n. 11 sekuntia ja Perl versio n. 5 sekuntia.

Koodia: [Valitse]
#!/usr/bin/env perl

my $n = 1032445450;
my @factors = ();
my $i = 1;

while($i < $n) {
  if ($n % $i == 0) {
    $n /= $i;
    push(@factors, $i);
  }
  $i++;
}

push(@factors, $n);
@factors = sort { $a <=> $b } @factors;

# identtinen tulostus Python version kanssa
my $last = pop(@factors);
print "[";
foreach(@factors) { print "$_, "; }
print "$last]\n";

Koodia: [Valitse]
#!/usr/bin/env python3

n = 1032445450
factors=[]
i=1

while(i < n):
  if (n % i == 0):
    n //= i
    factors.append(i)
  i += 1

factors.append(n)
factors.sort()

print(factors)

SuperOscar

  • Käyttäjä
  • Viestejä: 4000
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #35 : 23.05.12 - klo:18.56 »
Noiden regexpien käyttäminen ei välttämättä tuo ilmi koko totuutta. Python skriptin alussa on "import re", mikä siis tarkoittaa että ladataan lisäpalikka joka on itsessään kirjoitettu C:llä, eli tässä todennäköisesti verrataan Perlin ja Pythonin regexp toteutuksia keskenään, jotka molemmat on tod.näk. konepellin alla kirjoitettu C:llä.

Toki, mutta kiistamme ennakko-oletuksiin tämä testi sopi mainiosti. Tietysti vielä paremmin sopisi sellainen testi, jossa säännöllisen lausekkeen perusteella pitäisi löytää varioiva merkkijono, jota ei myöskään korvattaisi vakiojonolla vaan jolle pitäisi tehdä jotakin. (Esim. kääntää ”Meikäläinen, Matti” -> Matti Meikäläinen tai M. M.)

Raskas laskenta tehdään sitten tietysti mahdollisuuksien mukaan jotenkin muuten.
pöytäkone 1, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; NUC: openSUSE Leap 15.5; RPi 1: FreeBSD 14-RELEASE; RPi 2: LibreELEC 11

Tommi S.

  • Käyttäjä
  • Viestejä: 240
    • Profiili
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #36 : 23.05.12 - klo:19.13 »
Tein vielä testin jossa ensin kirjoitin yhden julmettoman ison tiedoston jossa on sekaisin kirjaimia ja keksittyjä sosiaaliturvatunnuksia, eli sisältö tällaista: "...othlbdetqnnwimwfzs270995-257Xavckvgim...". Tässä ei siis ole erillisiä rivejä, vaan koko roska on yksi pitkä rivi.

Tässä koodinpätkä joka generoi tuon tiedoston, omasta tiedostostani tuli n. 50 megan kokoinen. Tämä siis laittaa kaiken stdouttiin, josta sen voi tallettaa tiedostoon:
Koodia: [Valitse]
#!/usr/bin/env python3

from random import randint, choice
from string import ascii_uppercase, ascii_lowercase

def sosnum():
  return "%02d%02d%02d-%03d%s" % (
    randint(1,30),
    randint(1,12),
    randint(0,99),
    randint(1,600),
    choice(ascii_uppercase+"0123456789"))

for i in range(1,100000):
  for j in range(1,randint(100,1000)):
    print(choice(ascii_lowercase), end="")
  print(sosnum(), end="")

Sitten Perl ja Python skriptipätkät jotka lukevat stdinistä ja poimivat kaikki löytämänsä sos.turvatunnukset taulukkoon. Molemmat tulostavat lopuksi löytämiensä sos.turvatunnusten määrän ja kymmenen ensimmäistä taulukossa olevaa tunnusta. Omissa testeissäni Perl suoriutui urakasta n. 0,5 sekunnissa kun Pythonilta aikaa meni n. 3,5 sekuntia.
Tässä saattaa tosin vaikuttaa se että Python ei ilmeisesti voi tehdä tuota regexp operaatiota suoraan stdinille, vaan se joutuu ensin lukemaan sen kokonaan muistiin, kun taas Perl lähtee suoraan tekemään tuota hakua. Teen vielä yhden testin jossa tiedosto on pätkitty riveiksi, jos vaikka Python pärjäisi siinä tilanteessa paremmin.

Python:
Koodia: [Valitse]
#!/usr/bin/env python3

from sys import stdin
import re

m = re.compile('([0-9]{6}-[0-9]{3}[A-Z0-9])')
result = re.findall(m, stdin.read())

print(len(result))
print(result[0:10])

Perl:
Koodia: [Valitse]
#!/usr/bin/env perl

my @match = <STDIN> =~ m/([0-9]{6}-[0-9]{3}[A-Z0-9])/g;

print @match . "\n";
my @latest = @match[0..9];
print "['";
print join("', '", @latest);
print "']\n";

Tommi S.

  • Käyttäjä
  • Viestejä: 240
    • Profiili
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #37 : 23.05.12 - klo:19.29 »
Tein nyt testin vielä siten että pilkoin tuon tiedoston riveiksi, mutta yllättäen lopputulos ei muuttunut juuri ollenkaan, Python on edelleen n. 7 kertaa hitaampi kuin Perl, eli 3,5s vs. 0,5s.

Muokkaus: Tajusin juuri että tein tuon regexpin hieman hölmösti tuossa Python koodissa, eli tein re.findall(m, line) kun olisin voinut tehdä m.findall(line). Korjasin tuon nyt tuohon koodiin, mutta Python koodi ei nopeutunut kuin ehkä 0,05s, ja tuokin on niin pieni ero että on vaikea sanoa onko se sattumaa vai oikeaa nopeutumista.

Muokkaus2: Huomasin juuri että jos tuosta regexpistä jättää nuo sulkeet pois niin Python versio nopeutuu jonkin verran, ero on enää 2s vs. 0,5s Perlin hyväksi. Tein muutoksen allaoleviin koodipätkiin.

Tässä ohjelma joka generoi tiedoston:
Koodia: [Valitse]
#!/usr/bin/env python3

from random import randint, choice
from string import ascii_uppercase, ascii_lowercase

def sosnum():
  return "%02d%02d%02d-%03d%s" % (
    randint(1,30),
    randint(1,12),
    randint(0,99),
    randint(1,600),
    choice(ascii_uppercase+"0123456789"))

for i in range(1,100000):
  if (i % 10 == 0):
    print()
  for j in range(1,randint(100,1000)):
    print(choice(ascii_lowercase), end="")
  print(sosnum(), end="")

Tässä Python lukija:
Koodia: [Valitse]
#!/usr/bin/env python3

from sys import stdin
import re

m = re.compile('[0-9]{6}-[0-9]{3}[A-Z0-9]')

result = []

for line in stdin:
  result += m.findall(line)

print(len(result))
print(result[0:10])

Ja tässä Perl lukija:
Koodia: [Valitse]
#!/usr/bin/env perl

my @found = ();
my @match;

while(<STDIN>) {
  @match = $_ =~ m/[0-9]{6}-[0-9]{3}[A-Z0-9]/g;
  push(@found, @match);
}

print @found . "\n";
my @first = @found[0..9];
print "['";
print join("', '", @first);
print "']\n";
« Viimeksi muokattu: 23.05.12 - klo:20.07 kirjoittanut Tommi S. »

SuperOscar

  • Käyttäjä
  • Viestejä: 4000
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #38 : 23.05.12 - klo:21.46 »
Free Pascal näkyy elävän, joten täsmennetään:

Koodia: [Valitse]
uses sysutils,
      regexpr; { pitää olla: oldregexpr ainakin Archissa }

Tein nyt testin vielä siten että pilkoin tuon tiedoston riveiksi, mutta yllättäen lopputulos ei muuttunut juuri ollenkaan, Python on edelleen n. 7 kertaa hitaampi kuin Perl, eli 3,5s vs. 0,5s.

50 megan tiedostolla tuo ero ei vielä ole mahdottoman suuri vaikka ”seitsemän kertaa hitaampi” onkin. Saatko kokeilluksi saman 500 megan tiedostolla, joka olisi lähempänä todellista testiä?

Sinänsä en epäile, en vain juuri nyt kerkeä itse kokeilemaan, kun pitää korjata tänäisiä yliopiston valintakokeita :)
pöytäkone 1, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; NUC: openSUSE Leap 15.5; RPi 1: FreeBSD 14-RELEASE; RPi 2: LibreELEC 11

Tommi S.

  • Käyttäjä
  • Viestejä: 240
    • Profiili
Vs: Nopeuskisa: Perl vastaan Python – voiko olla totta?
« Vastaus #39 : 24.05.12 - klo:18.52 »
50 megan tiedostolla tuo ero ei vielä ole mahdottoman suuri vaikka ”seitsemän kertaa hitaampi” onkin. Saatko kokeilluksi saman 500 megan tiedostolla, joka olisi lähempänä todellista testiä?

Lisäsin testitiedoston generoivan skriptin silmukkaan yhden nollan ja 535 megan tiedostolla ajat ovat Perl n. 5 sekuntia ja Python noin 20 sekuntia, eli melko täsmälleen ne samat kertoimet jotka saatiin jo 50 megan tiedostolla (kun oltiin poistettu regexpistä sulkeet, jotka jostain syystä oleellisesti hidastivat Pythonia).

Tuosta 50 megan tapauksestakin voi laskea että jos on vaikka 100kpl 50 megan tiedostoa niin siinä missä Perlillä menee kaikkien noiden läpikäymiseen 0,5s * 100 = 50s, niin Pythonilta menee samaan urakkaan 2,0s * 100 = 3min20s.