Davvero su Solaris Python 3 fa meglio di C?

Un programma per computer non è altro che una serie di istruzioni date alla CPU, che le esegue; un programmatore usa un linguaggio (di programmazione, per l’appunto) per descrivere le operazioni, lasciando che un programma apposito traduca queste operazioni nelle istruzioni.
A seconda di questo programma, iI linguaggi si possono dividere in due grandi categorie:

  • compilati
    I programmi in questa categoria richiedono il compilatore, che legge tutto il codice sorgente e lo traduce in un eseguibile per un determinato processore. Questa fase normalmente richiede molto tempo, e il prodotto è specifico per un processore, o al più una categoria di processori; in compenso hanno il vantaggio di essere i più veloci nell’esecuzione.
  • interpretati
    I comandi che formano i programmi di questa categoria sono letti da un interprete ed eseguiti immediatamente, uno ad uno. Questo porta e performance scarse, ma permette di modificare un programma e vedere gli effetti immediatamente, senza aspettare la fase di compilazione; inoltre, lo stesso codice può essere eseguito su varie piattaforme: è l’interprete ad essere specifico, non il programma.

A quest’ultima tipologia appartengono alcuni linguaggi che ampiamente apprezzati, come Python. E proprio di Python (versione 3) parliamo, perché qualche giorno fa è comparso sul blog di Oracle un post con questo titolo:

Reimplementing a Solaris command in Python gained 17x performance improvement from C

La reimplementazione di un comando Solaris in Python migliora di 17 volte le performance rispetto a C

Vista la (lunga) premessa, sarete meravigliati anche voi: ma come?! Un linguaggio interpretato funziona 17 volte meglio di uno compilato? Tra l’altro, del campione in assoluto, C! Possibile?

In effetti c’è il trucco (e lo spiega lo stesso autore del post): il codice in C e quello in Python sono diversi; non solo come linguaggio, ma come algoritmi usati.
Per dirla in maniera più semplice: fanno sì la stessa cosa, ma in modi diversi.

Nel caso specifico si tratta del comando /usr/bin/listusers di Solaris, che si preoccupa di mostrare in maniera ordinata l’elenco di utenze presenti su un sistema, eventualmente filtrato per gruppi e/o nome utente.
Quando fu scritto il codice C, i dati da gestire erano pochi: miglioramenti delle performance relative anche importanti si sarebbero tradotte in miglioramenti di perfomance assolute marginali. Per chiarici con un esempio: impiegare 5 ms invece di 100 ms è un miglioramento di 20 volte, ma per l’utente è abbastanza rapido anche quello “scarso”.
Il risultato è che quelle 800 righe di codice hanno 30 anni, praticamente non modificate.

La nuova implementazione in Python sfrutta delle capacità del linguaggio assenti in C, ovvero lavorare facilmente con set di dati, come le liste. Questo ha portato a riscrivere il programma in circa 100 righe (cosa che lo rende anche più semplice) e a usare meccanismi migliori per filtrare o riordinare i dati: sono questi meccanismi a portare l’aumento di prestazioni.

Probabilmente una reimplemetazione apposita con un linguaggio compilato (C o C++, ma anche Go o Rust) potrebbe portare ad una performance ancora migliore, e visto che ora gli elenchi di utenze possono superare tranquillamente le decine di migliaia, un miglioramento del genere potrebbe essere sensibile.

Qualcuno vuole cimentarsi? 🙂

Ho coltivato la mia passione per l'informatica fin da bambino, coi primi programmi BASIC. In età adulta mi sono avvicinato a Linux ed alla programmazione C, per poi interessarmi di reti. Infine, il mio hobby è diventato anche il mio lavoro.
Per me il modo migliore di imparare è fare, e per questo devo utilizzare le tecnologie che ritengo interessanti; a questo scopo, il mondo opensource offre gli strumenti perfetti.

Tags: , ,