Kirjoittaja Aihe: BASH kääntäjä joka on repoissa  (Luettu 2034 kertaa)

petteriIII

  • Käyttäjä
  • Viestejä: 601
    • Profiili
BASH kääntäjä joka on repoissa
« : 27.09.15 - klo:11.50 »
Onko kenelläkään kokemuksia repoissa olevasta BASH-kääntäjästä nimeltään shc ? Mitä koetin niin toimiihan se, mutta eihän äkkiseltään mitään varmaa voi sanoa.

Shc käänsi vaikeatkin skriptit todella nopeasti - ja käännökset tuntuivat toimivan. En kylläkään tiedä onko kääntäjälle tarvetta sillä oikeinkasatut skriptit ovat sinälläänkin tarpeeksi nopeita. Ja koodin kätkeminen binäärimuotoon on sairasta mikäli kätkemisen syy on pelkästään kätkeminen.

Tuosta nopeutuksesta muuten: kun alkaa soveltamaan kunnolla sed, awk, bc ... niin skriptit nopeutuu yli kymmenkertaisesti. Ja silti kahdella verkkosivulla on osoitettu että awk, sed ... hidastavat; BASH oli satakunta kertaa nopeampi kuin ne - mutta oikean koodin löytäminen edellyttää skriptaajalta täydellistä asennemuutosta.

Tutkin enemmän tuota väitettä että awk, sed ja grep hidastavat joskus 100kertaisesti ja osoittautui että väitteessä oli pikkuriikkisen perääkin. Viisainta olla puhumatta läpiä päähäni ja vain antaa muutama käytännön esimerkki: 
Koodia: [Valitse]
echo $tekstijono | sed 's/jotakin/joksikin_muuksi/g'         # usein tulee kirjoitettua näin varsinkin kun näin on aikoinaan oppinut ja näin on helppoa kirjoittaa
echo ${tekstijono//jotakin/joksikin_muuksi}                  # tämä on noin 100 kertaa nopeampi. Vaikka monet tuntee tämän niin eipä paljoa näy.
Koodia: [Valitse]
sed 's/jotakin/joksikin_muuksi/g' tiedosto                   
a=$(cat tiedosto); echo -e "${a//mikä/miksi}"                # tämä on paljonkin hitaampi, mutta sed:iä ei tarvita. echo -e on muuten hieman nopeampi kuin pekkkä echo
Koodia: [Valitse]
grep -o ascii-merkki tiedosto | wc -w                        # merkin sijaan voi kirjoittaa sanan tai muuttujan jossa voi olla mitävain.
tr -dc ascii-merkki < tiedosto | wc -w                       # tämä on kymmenen kertaa nopeampi. Tosin kelpaa yksinomaan yksittäisille ascii-merkeille
Koodia: [Valitse]
awk '{print $2}' tiedosto > /dev/null
cut -d ' ' -f 2 tiedosto > /dev/null                         # tämä on yli 2* nopeampi
« Viimeksi muokattu: 15.10.15 - klo:18.20 kirjoittanut petteriIII »

kamara

  • Käyttäjä
  • Viestejä: 2357
    • Profiili
Vs: BASH kääntäjä joka on repoissa
« Vastaus #1 : 27.09.15 - klo:13.54 »
Minä en ainakaan käytä bash-scriptejä sen takia, että sen suoritusaika on nopea, vaan että sen luominen on nopeaa, joten en kaipaa kääntäjää.

Ja koodin kätkeminen binäärimuotoon on sairasta mikäli kätkemisen syy on pelkästään kätkeminen.

Tässä olen samaa mieltä.

nm

  • Käyttäjä
  • Viestejä: 13761
    • Profiili
Vs: BASH kääntäjä joka on repoissa
« Vastaus #2 : 27.09.15 - klo:20.38 »
Onko kenelläkään kokemuksia repoissa olevasta BASH-kääntäjästä nimeltään shc ? Mitä koetin niin toimiihan se, mutta eihän äkkiseltään mitään varmaa voi sanoa.

Shc käänsi vaikeatkin skriptit todella nopeasti - ja käännökset tuntuivat toimivan. En kylläkään tiedä onko kääntäjälle tarvetta sillä oikeinkasatut skriptit ovat sinälläänkin tarpeeksi nopeita. Ja koodin kätkeminen binäärimuotoon on sairasta mikäli kätkemisen syy on pelkästään kätkeminen.

shc ei käännä itse skriptiä vaan käsittelee sitä pelkkänä merkkijonona, joka kryptataan ja paketoidaan binääriin, joka purkaa sen ja syöttää komentotulkille. Skriptin sisällöllä tai monimutkaisuudella ei siis käytännössä ole merkitystä, eikä prosessilla saavuteta mitään suorituskykyetua. Lisäksi alkuperäisen skriptin purkaminen shc:n luomasta binääristä on suhteellisen triviaalia.


Tuosta nopeutuksesta muuten: kun alkaa soveltamaan kunnolla sed, awk, bc ... niin skriptit nopeutuu yli kymmenkertaisesti. Ja silti kahdella verkkosivulla on osoitettu että awk, sed ... hidastavat; BASH oli satakunta kertaa nopeampi kuin ne - mutta oikean koodin löytäminen edellyttää skriptaajalta täydellistä asennemuutosta.

Kun kutsut ulkoisia komentoja skriptissä, järjestelmä joutuu käynnistämään uuden prosessin jokaisen kutsun yhteydessä. Jos siis komento suorittaa jonkin yksinkertaisen operaation ja sitä ajetaan silmukassa vaikkapa tuhansia tai miljoonia kertoja, nopeusero komentotulkin sisällä, samassa prosessissa suoritettavaan vastaavaan aliohjelmaan voi olla helposti kymmen- tai satakertainen

Jos taas ulkoinen kutsu tekee jonkin monimutkaisemman operaation, joka kestää ainakin sekunnin kymmenyksiä, ja vastaava bash-toteutus on hitaampi tai hankalampi koodata, ulkoisen työkalun käyttäminen voi hyvinkin olla järkevää.

petteriIII

  • Käyttäjä
  • Viestejä: 601
    • Profiili
Vs: BASH kääntäjä joka on repoissa
« Vastaus #3 : 28.09.15 - klo:18.33 »
Kun kutsut ulkoisia komentoja skriptissä, järjestelmä joutuu käynnistämään uuden prosessin jokaisen kutsun yhteydessä. 

Voiko sed- awk- grep:ille ... avata jotain omaa aluetta niin ettei jokaisella kutsulla avattaisi omaa prosessia?

nm

  • Käyttäjä
  • Viestejä: 13761
    • Profiili
Vs: BASH kääntäjä joka on repoissa
« Vastaus #4 : 28.09.15 - klo:18.58 »
Voiko sed- awk- grep:ille ... avata jotain omaa aluetta niin ettei jokaisella kutsulla avattaisi omaa prosessia?

Ei voi. Nuo ovat erillisiä ohjelmia, joiden jokainen ajokerta edellyttää uuden prosessin luomista. Vaihtoehtona olisi muokata ja kääntää ohjelma kirjastoksi ja integroida toiminnallisuus komentotulkkiin. Sedin, Awk:n ja Bashin yhdistelmästä tulisi kyllä aikamoinen frankenshell.

Käytännössä voit kuitenkin usein tehdä yhdellä kutsulla paljon asioita, eli esim. sedille voisi putkittaa suuren määrän käsiteltäviä rivejä sen sijaan että kutsuisit ohjelmaa yksitellen jokaiselle riville.


Jos suorituskyky on oikeasti olennaista, katse kääntyy Go:n, Rustin, D:n tai C/C++:n suuntaan. Tai johonkin kymmenistä muista tehokkaista käännettävistä kielistä. Tulkattavista skriptikielistä Python ja Perl ovat huomattavasti Bashia kehittyneempiä ja niistä löytyy valmiina tai lisämoduuleina kaikki tarvittava.

Itse kirjoitan shell-skriptejä nimenomaan silloin kun on tarvetta ajaa järjestelmäkomentoja ja kutsua useita erillisiä binäärejä tai putkittaa asioita ohjelmien välillä. Komentotulkki toimii siis liimana tai purkkana, jolla rakennelma pystytetään nopeasti ja pienimmällä vaivalla. Jos taas on tarvetta laskea jotain tai vaikkapa pyöritellä merkkijonoja useamman säännöllisen lausekkeen läpi, otan käyttöön järeämmät työkalut. Yleensä Python on seuraava askel, mutta suorituskykykriittisen koodin tapauksessa on joskus parempi hypätä suoraan käännettäviin kieliin.