In parole semplici
Immagina Foglio diviso in due parti. Quella che vedi (finestre, menu, la griglia di celle) è scritta con gli strumenti di Apple, quindi ha l'aspetto e il comportamento di tutte le altre app del Mac. Quella che fa i conti (legge i file, interpreta le formule, ricalcola) è un motore separato scritto in Rust, un linguaggio che produce programmi molto veloci e compatti.
Le due parti comunicano attraverso un'interfaccia piccola e semplice. In mezzo non c'è nient'altro: nessun browser nascosto, nessuna macchina virtuale, nessun runtime da scaricare. Ecco perché l'intera app pesa 7,5 MB, si apre in 0,24 s e usa circa 58 MB di memoria con un foglio vuoto.
L'app per Mac: Swift e AppKit
L'interfaccia è scritta in Swift con AppKit, il framework su cui si basano il Finder e gran parte delle app di sistema. I documenti sono veri documenti macOS: Apri recenti, Salva con nome, Ripristina, Duplica, pannelli nelle finestre, schermo intero, modalità scura, stampa ed Esporta PDF funzionano come ti aspetti.
Il foglio è una griglia NSView disegnata su misura, non un controllo tabella standard. Chiede al motore solo le celle visibili, in blocchi pronti da disegnare: così lo scorrimento resta fluido anche su fogli con centinaia di migliaia di righe. Anche grafici, immagini e barra della formula sono disegnati dall'app.
Foglio contiene inoltre un proprio lettore di metafile EMF e WMF, il formato di immagini vettoriali dei vecchi documenti Office (clip art, equazioni MathType, diagrammi Visio incollati). Immagini che altre app Mac mostrano come riquadri vuoti vengono disegnate correttamente e salvate senza modifiche.
Il motore: Rust e un IronCalc migliorato
Le formule vengono interpretate e calcolate da IronCalc, un motore per fogli di calcolo open source in Rust. Foglio usa un fork migliorato di IronCalc 0.9.1, con ogni modifica segnalata e documentata nel repository.
Il fork aggiunge il ricalcolo incrementale: quando modifichi una cella vengono ricalcolate solo le formule che dipendono da essa, non l'intera cartella. Su una cartella da 100.000 righe e 300.000 formule una modifica richiede 16 ms; un ricalcolo completo 64 ms.
Aggiunge anche le ricerche indicizzate. Il primo CERCA.VERT, CONFRONTA o CERCA.X su un intervallo lo legge una volta e costruisce un indice; le ricerche successive sono un singolo accesso all'indice. 1.000 CERCA.VERT esatti su 10.000 righe sono passati da 1.703 ms in IronCalc originale a 1,3 ms nel fork di Foglio. Il fork corregge inoltre una dozzina di funzioni, tanto che 191 delle 195 funzioni della verifica di compatibilità danno gli stessi risultati di Excel in ogni caso di prova.
- I vecchi
.xls, i binari.xlsbe gli.odsdi LibreOffice vengono letti con calamine, un lettore veloce scritto in Rust. - I file CSV e TSV passano da un importatore in Rust che riconosce la codifica del testo, il separatore e il separatore decimale.
- Le formule scritte in italiano, tedesco, spagnolo o francese vengono tradotte nella forma standard inglese di Excel prima di essere salvate.
Il ponte: una semplice interfaccia C
Il motore in Rust viene compilato come libreria statica ed espone una piccola interfaccia C (foglio_core.h): aprire e salvare un file, modificare una cella, restituire un blocco di celle visibili. Swift la chiama direttamente tramite un bridging header. Nessun binding generato, nessun framework, nessun messaggio tra processi: una chiamata al motore costa più o meno quanto una normale chiamata di funzione.
Niente progetto Xcode
Foglio si compila con due comandi: cargo costruisce la libreria Rust e swiftc compila l'app e la collega. Uno script produce un'app universale per Apple silicon e Intel e la impacchetta in un'immagine disco con hdiutil, lo strumento di Apple. Servono gli Xcode Command Line Tools e Rust; Xcode completo non è necessario.
Meno strati significa meno cose che possono rompersi, compilazioni più rapide e un progetto che chiunque può leggere da cima a fondo.
Testato con tastiera e mouse veri
Foglio ha 69 test dell'interfaccia che usano l'app reale con eventi di tastiera e mouse reali: scrivere formule, riempire intervalli, ordinare, annullare, salvare e riaprire file. Gli importatori di file e il motore di calcolo hanno le proprie suite di test in Rust, e una modalità speciale confronta ogni ricalcolo incrementale con un ricalcolo completo.
Perché tutto questo rende Foglio piccolo e veloce
Un'app Electron contiene una copia completa del browser Chromium, di solito ben oltre 100 MB prima ancora di fare qualcosa. Una suite Java o multipiattaforma porta con sé il proprio runtime e il proprio toolkit grafico. Foglio contiene solo il proprio codice e usa i framework già presenti su ogni Mac.
Il motore in Rust è compilato con l'ottimizzazione completa in fase di link e senza simboli di debug. Il risultato è un'app universale di circa 19 MB su disco, 7,5 MB come download compresso, che a riposo usa lo 0 % della CPU.