Un post gustosamente tecnico, inevitabile epilogo di una giornata interamente passata a programmare manipolando una infinita' di strutture dati.
Gia' da tempo ho constatato l'enorme gap che esiste tra le strutture dati comunemente conosciute, usate ed implementate nelle piu' svariate librerie, e l'architettura di un qualsiasi sistema la cui complessita' e' maggiore del classico hello world: laddove, seguendo i canoni della programmazione strutturata, si isolano (e stratificano...) le routines in modo da essere quanto piu' generiche possibili, alla lunga molto facilmente si arriva a replicare gli stessi dati in piu' e piu' posti semplicemente perche' in diversi posti si necessita di un diverso ordinamento, di una diversa gerarchia o di un diverso tipo di elemento che possa essere passato alle funzioni esposte da un diverso framework. E la pigrizia, prima virtu' di ogni developer, induce a ridurre, se non eliminare del tutto, l'implementazione di nuove strutture dati ad hoc da adottare caso per caso, ma ad adoperare due o tre o quattro istanze delle strutture normalmente fornite da qualsiasi libreria di utility e gestite su piu' piani differenti.
Un esempio concreto, fresco fresco e tratto dall'esperienza di oggi: ho usato una GHashTable per mantenere i riferimenti ad alcuni oggetti presi da un'altro componente e da restituire ad un'altro. Ma tali componenti ai due estremi del flusso sono fatti per "ragionare" secondo parametri diversi di cotali oggetti, mentre l'hash table permette di indicizzarli secondo un criterio solo. Risultato: quando le richieste arrivano da una parte l'accesso e' immediato, quando arrivano dall'altro devo convertire in una GList allocata sul momento, iterare, e liberare la struttura temporanea. Quanto sarebbe piu' efficiente il tutto se realizzassi una hash table personalizzata con due (o meglio ancora, un numero arbitrario di) indici distinti, o meglio ancora perfezionassi la gia' esistente GRelation (che non sembra godere di molta attenzione da parte del team Glib)? Molto, tutto sta nell'avere tempo di farlo.
E ancora: come detto gli oggetti sono presi da una parte e passati dall'altra, ma questo comporta una duplicazione delle stesse informazioni. Informazioni che sono rappresentate in modi completamente diversi, ma che vanno ordinate piu' e piu' volte, iterate piu' e piu' volte, sincronizzate piu' e piu' volte... Quanto sarebbe piu' rapido e performante l'insieme se si provvedesse ad una qualche forma di struttura condivisa mantenuta allineata una sola volta per tutte? Molto, ma richiederebbe non poco sforzo per la realizzazione di qualcosa di stabile date le condizioni di concorrenza.
E' probabile (anzi pressoche' certo) che la' fuori esistano centinaia di concetti nuovi, magari gia' anche implementati e testati e debuggati, ma che non sono ancora stati "scoperti" ed introdotti nei toolkit piu' popolari, i quali spesso magari neppure implementano le gia' ben note strutture piu' di nicchia e raffinate.
Nel contesto del Progetto Lobotomy iniziai ad esplorare, insieme ad altri spunti per esotiche strutture dati tra cui una ispirata dalle architetture multi-core, il concetto di "extension", ovvero estensioni dei tipi di dato fondamentali con altri oggetti che li descrivessero in modi diversi e ad essi direttamente agganciati al fine di avere un'unica lista in cui aggiungere e rimuovere elementi ed in cui cercare secondo un criterio ed ottenere immediatamente la diversa rappresentazione (ad esempio: cercare un HyppoVFSItem ed avere subito il relativo all'interno della GtkIconView senza dover iterare altrove), ma tanto per cambiare non ebbi modo di approfondire ulteriormente le potenzialita' del concept e non ottenni alcunche' di effettivamente usabile.
Un giorno o l'altro dovro' tornarci, su questo e su altre ricerche. Per intanto mi accontento delle mie hash table tradotte in liste...
Nessun commento:
Posta un commento