Kedvelem az awk-t

Adódott, hogy egy villamos hálózatot kellett számolgatnom mindenféle frekvencián, természetesen szükségem volt komplex aritmetikára. Írtam egy nyúlfarknyi scriptet calc-ban. A calc ismeri a komplex számokat, a műveletek is értelmezve vannak a komplex számok halmazán. Pontosan nem mértem le a scriptem futásidejét, de nagyhából 1 óra és 52 perc volt.

Ugyanezt a scriptet megírtam awk-ban. Az awk nem ismeri a komplex aritmetikát, így a komplex számok szorzását, osztását, a belőlük történő abszolútérték négyzetének illetve abszolútértékének számítását végző függvényeket is megírtam. Az awk script futásideje 1.947 s volt.

A két script által számított eredmény hajszál pontosan megegyezett. Az awk-s script viszont 3450-szer gyorsabban futott le. :)

Időközben megmértem octave-val is. 10.935 s lett a futásidő, tehát szűk 11 másodperc. Ez az awk kevesebb, mint 2 másodpercéhez képest lényegesen rosszabb, de használható, szemben a calc majdnem 2 órás futásidejével.

Hozzászólások

Kíváncsi volnék egy matlab vagy octave eredményre.

Octave-ban lehet, hogy megírom. Tegyük hozzá, octave-ot eddig egyetlen alkalommal használtam, lényegében komplex együtthatós, sok ismeretlenes lineáris egyenletrendszer megoldására Gauss-eliminációval. Az is gyorsan futott. Azért nem eleve octave-ot használtam, mert nem ismerem a szintaxisát, tanulnom kellett volna, a calc-ot meg ismerem. Aztán az awk-t is, a komplex mul() és div() függvények megírása pedig nem akkora kihívás.

Érzésem szerint az awk gyorsasága részben abból jön, hogy köztes kódra fordít első körben, nem a szöveges scriptet bogarássza jelen példában 274000-szer - ennyiszer fut le a ciklusmag a konkrét scriptben. A másik ok, hogy használhatja az aritmetikai coprocessort, tehát a lebegőpontos műveletek hardware támogatással, nagyon gyorsan történhetnek.

Ezzel szemben a calc racionális törtként ábrázolja a számokat, de akár nagyon hosszan, például az 1000 faktoriálisát az utolsó számjegyig kiírja, nem lebegőpontosan adja meg a mantissza adott pontosságával. Ebből viszont az következik, hogy memóriában - jó, gondolom, cache-ben -, a CPU-ra támaszkodva, software-esen számol mindent.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Tehát ha jól értem akkor a calc inkább tudományos számításokhoz előnyösebb, ahol jobban számít a számítás pontossága, mint annak sebessége. Azonban neked inkább egy kevésbé pontos, de gyors mérnöki feladat megoldásra volt szükséged, amire a calc ezek szerint kevésbé alkalmas. Pontosan ezért érdekel az octave, mivel az úgy gondolom inkább mérnöki felhasználásra készült.

Btw. ha már ezek a szoftverek szóba kerültek, hobbira én a SMath Studiot szoktam néha használni papír és toll helyett.

Na, megcsináltam octave-ban is. 10.935 s lett a futásidő. Ez jelentősen rosszabb az awk 2 másodpercen belüli futásidejénél, de bőven használható a 11 másodperc még. A calc majdnem két órája kicsit fájdalmas volt. Az eredmény természetesen itt is ugyanannyi lett.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ezek szerintem nem kezelik alapértelmezetten a komplex számokat. Persze tömbök használatával megoldható, de ha már meg kell oldani, ugyanott vagyok, mint az awk-val. Sajnos az awk sem kezel komplex számokat. Igaz, az awk elsősorban szöveg feldolgozására lett kitalálva, nem matematikai programnak, mindamellett ez utóbbi célra is használható.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Így van. Nincs komplex számkezelés bennük, csak saját számábrázolás "tetszőleges" pontossággal. (Esetleg ha valahol publikálod a kódjaidat, akkor lehet kapsz alternatív / javított - és így esetleg gyorsabb lassabb változatokat.)

=====
tl;dr
Egy-két mondatban leírnátok, hogy lehet ellopni egy bitcoin-t?

awk? Micsoda ezoteria. En biztos nem mentem volna messzebb a pythonnal, egyszeru, mint a faek, es ha bonyolodik a helyzet, akkor a fel vilag ott van a hatad mogott (lasd pl. numpy/scipy, de a pythonnak az egyik specialitasa a matekos konyvtarai). Futasidoben az awk-hoz, programirasi idoben a calc-hoz lennel kozelebb :)

Nem ismerem őket. Amúgy jobb szeretem magam levezetni, megálmodni azt, amit szeretnék, jobban kézben tudom tartani a dolgokat. Ez nagyjából olyasmi, mint amikor mikrokontrollerre csak assembly-ben programozok, mert fogalmam sincs, C-ből mire fordul majd. Teszem azt, assembly-ben azt is megcsinálom, hogy egy adott helyre a közbeeső feltételek teljesülésétől függetlenül ugyanannyi idő alatt érjen a processzor futása, míg magas szintű nyelvnél - s a C ebben az értelemben már az -, valahogy lesz, de ki tudja, hogyan.

Az eredeti problémát illetően: a konkrét esetre csinálok valami levezetést, aztán numerikusan végigszámoltatom a géppel.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Egy C-hez, awk-hoz, stb-hez erto embernek vajon mennyi ido megirni egy Python scriptet? Gyakorlatilag nulla plusz ido. Meg a "fejlesztokornyezet" (pl. ipython) letoltese tart a legtovabb, ha az, ami a Linuxban alapbol benne van, nem eleg kenyelmes.

Raadasul ez a befektetes hatvanyozottan megterul. Nekem az jott ki, hogy ha ket-harom sornal hosszabb bash/perl/awk/akarmi kell, akkor az mar pythonban gyorsabb, egyszerubb, karbantarthatobb.

(Amugy rendes programozashoz ruhellem a Pythont, mert az absztrakcios eszkoztara "by design" erosen limitalt, de van, amihez tokeletes...)

A python-tól csak messzebb mennék... Minél messzebb :-D A viccet félretéve, ha valaki ismer több eszközt, az jó, ha ki tudja választani az adott célra optimálisat, az még jobb. Nem tudni, hogy pontosan miket számoltatott végig a kolléga, de nekem gyanús, hogy valahol erősen szuboptimálistra sikeredett vagy a script, vagy a calc megvalósítása...

Én is kedvelem az AWK-t, régen sokat használtam.

Manapság ilyenre inkább az Ammonite-ot használom.
Számításokhoz nagyon jó a spire könyvtár, betöltjük:


load.ivy("org.typelevel" %% "spire" % "0.14.1")
@ import spire.implicits._
@ import spire.math._

Máris számolhatunk complex számokkal:


@ Complex(5.0, 3.0).sin
res1: Complex[Double] = Complex(-9.654125476854839, 2.841692295606352)

Akár tetszőleges pontossággal:


@ Complex(BigDecimal(5.0), BigDecimal(3.0)).sin
res2: Complex[BigDecimal] = Complex(-9.654125476854839136551543634030165992, 2.84169229560635194381687539530623643)

Használhatunk más szám típusokat (van 14 új), pl. a racionálist:


@ Rational(5) / Rational(3)
res3: Rational = 5/3

...és még ezer jóság.

Én FFT-t írtam meg többek között AWK-ban és Python-ban.
i5-3337u procik 4k FFT

gAWK: 90 ms
Pypy: 0,74 ms, cPython: 13 ms
C: 0,16 ms

Python Pypy-vel sokkal gyorsabb az AWK-nál, továbbá a Python rendesen viszi a komplex számot.