Bygg och kompilera: Skillnader mellan kompilator och tolk

📖 13min read

Maskiner kan inte engelska

När jag först lärde mig C-språket i skolan var det något jag inte förstod mest. ”Varför körs inte min kod direkt, men måste den gå igenom den irriterande processen att bygga och kompilera?”

Python startar direkt när du skriver kod och trycker på enter, men Java och C kräver tidskrävande steg. När jag var en student på grundutbildningen tänkte jag bara: ”Varje språk har olika grammatik.” När jag dök upp på provet behövde du bara svara ”C är ett kompilerat språk, Python är ett tolkat språk”.

Men när jag arbetade med back-end-servrar som hanterar stora mängder trafik i praktiken, insåg jag att denna enkla skillnad var en enorm barriär som avgjorde systemets prestanda och distributionshastighet. Den eleganta koden jag skrev var i själva verket bara ett okänt främmande språk för den okunniga och samvetsgranna arbetaren som kallas CPU.

Översättning är nödvändig mellan språket vi använder och språkmaskinerna.

Vad i hela friden är ”Bygg”?

Så vad är egentligen en konstruktion? Hur skiljer det sig från att bara ”spara”?

Källkoden vi skrev (.java, .c) är faktiskt bara en textfil. Det är en ”text” som kan läsas även när den öppnas med anteckningsblock. Datorer (CPU) vet dock inte hur de ska läsa. Du kan bara veta om elen flödar (1) eller inte (0).

Build är en omfattande paketeringsprocess som konverterar ”textfilen” vi skrev till en ”körbar fil (.exe, .class, .jar) som en dator kan köra.

Med andra ord, om källkoden är ett ”matlagningsrecept (papper)”, är build processen att trimma och steka ingredienserna enligt receptet och servera en ”färdig rätt (mat)”. Oavsett hur mycket du ändrar receptet (koden), om du inte lagar (bygger) det igen, ligger den kalla maten du gjorde igår kvar på bordet (servern).

Arbetsinstruktioner för digitalt distributionscenter

För att förstå denna komplexa process, jämför insidan av en dator med ett gigantiskt digitalt logistikcenter.

Här är CPU en arbetare som är otroligt snabb, men som inte har någon flexibilitet. Den här arbetaren kan bara läsa arbetsinstruktioner som kallas maskinspråk (0 och 1).

Att skriva kod i Java eller Python är processen att skapa en ”arbetsmanual” att ge till arbetare. Men problemet är att vi skriver den här manualen på engelska (programmeringsspråk). Arbetaren kan inte engelska. Så vi behöver översättare. Ett språks öde beror på denna översättningsmetod.

1. Kompilator: Professionell översättare som översätter i förväg

2. Tolk: Realtidssimultantolk

Det är skillnaden mellan att översätta i förväg (hastighet) och att tolka i farten (flexibilitet).

[Kodverifiering] Verifierar maskinspråkets blotta yta

Jag kan inte riktigt känna det bara av att höra det. Låt oss visuellt kontrollera om Python verkligen översätter rad för rad och hur koden som maskinen ser ser ut.

Python har en modul som heter dis (Disassembler). Med detta kan du se vilka instruktioner som internt är uppdelade i Python-kod när den exekveras.

import dis

def my_function():
    a = 10
    b = 20
    print(a + b)

# Kontrollera vilken maskinkod (bytekod) Python-koden konverteras till
print("--- Python Bytecode Verification ---")
dis.dis(my_function)

När du kör den här koden matas följande främmande språk ut.

  5           0 LOAD_CONST               1 (10)
              2 STORE_FAST               0 (a)

  6           4 LOAD_CONST               2 (20)
              6 STORE_FAST               1 (b)

  7           8 LOAD_GLOBAL              0 (print)
             10 LOAD_FAST                0 (a)
             12 LOAD_FAST                1 (b)
             14 BINARY_ADD
             16 CALL_FUNCTION            1
             18 POP_TOP
             20 LOAD_CONST               0 (None)
             22 RETURN_VALUE

Analys:

Å andra sidan, när det kompileras, översätts C-språket direkt till det faktiska CPU-sammansättningsspråket, såsom MOV EAX, 10 (lägg 10 i EAX-registret). Eftersom det inte finns några mellanchefer har den inget annat val än att vara snabb.

Avvägning i praktiken: vilken ska man välja?

När jag var student var det bäst att vara bekväm. Snarare än C-språk, som har kompileringsfel, föredrog jag Python eller JavaScript, som enkelt kan skrivas och köras. Men i praktiken måste en hård avvägning göras mellan stabilitet och produktivitet.

1. Rädsla för runtime-fel (svaghet hos tolken)Det mest skrämmande när man bygger en server med Python är att servern stannar klockan 3 på morgonen på grund av ett enda stavfel. Tolken känner inte till felet förrän det körs (punkten där koden exekveras). Å andra sidan frågar Java (kompilerat språk) ”Jag gjorde ett stavfel här?” vid byggande. Och han berättar för mig. Denna stränga när det gäller att fånga misstag innan implementeringen blir en räddare i storskaliga projekt.

2. Tråkig byggtid (kompilatorns svaghet) Å andra sidan, när ett Java-projekt växer, kan det ta flera minuter att ändra och kontrollera en enda kodrad (Gradle Build…). Det är därför Python överväldigande används i de tidiga stadierna av startups där snabba ändringar och implementeringar är avgörande, eller i uppgifter som kräver omedelbara resultat, som dataanalys.

En strikt lärare (kompilator) är säker men frustrerande, och en snäll vän (tolk) är bekväm men försummar ibland misstag.

Avslutande: Teori blir ett vapen

Vi vet nu att ”bygga och kompilera”-processen och hur koden översätts varierar från språk till språk. I teorin skulle det vara det rätta svaret att välja det bästa språket utifrån projektets karaktär.

Men verkligheten var inte så snäll. Företaget jag gick med i hade redan en fast teknikstack, och även om jag gick med som Java-utvecklare var jag tvungen att röra Python, JavaScript och till och med Android XML.

Det som paradoxalt nog räddade mig från detta förvirrande fält av ’allätande utveckling’ var dessa ’grundläggande teorier’ jag lärde mig idag. Detta beror på att även om skalet på språket är annorlunda, är principerna som fungerar inom det desamma.

Nästa gång kommer jag att prata om min praktiska erfarenhet om hur jag ”dök djupt in i ett språk (Java) för att rikta in mig på andra språk” och varför grunderna är viktiga för att undvika att bli en slav av ramverket.

Lämna en kommentar