Valhalla: quando i domain diventano tipi e le prestazioni volano
Sicurezza dei tipi e prestazioni: come Project Valhalla sta cambiando Java
Se hai mai provato a usare Java per una architettura domain-driven, conosci il problema. Vuoi un tipo PositiveInt che garantisca valori positivi. Vuoi che il compilatore respinga gli stati non validi. Vuoi sicurezza a tempo di compilazione.
Poi arriva il codice critico. Un sistema che elabora milioni di eventi, ciascuno con un PositiveInt come identificatore. E all’improvviso quegli oggetti wrapper diventano un peso: 16 byte di overhead, allocazioni continue sullo heap, problemi di cache. La regola pratica che molti sviluppatori hanno seguito per anni è semplice: usa i tipi raffinati solo ai confini, poi torna ai primitivi quando serve velocità.
Project Valhalla sta per cambiare questa regola.
Il problema dei wrapper
Un wrapper come PositiveInt che contiene un solo int occupa 16 byte su HotSpot. Quando li metti in un array, non vengono memorizzati inline: l’array contiene solo riferimenti. Ogni accesso richiede una dereferenziazione, con il rischio di cache miss.
Il risultato è che il wrapper costa fino a quattro volte la memoria del primitivo che protegge. E questo crea un vincolo architettonico: i tipi di dominio funzionano bene alle API, ma nel momento in cui entri in un ciclo caldo devi rinunciare alla sicurezza per tornare a int o long.
Value Classes: sicurezza senza penalità
Con Java 27 Early Access arriva il value keyword. A differenza delle classi normali, le value classes non hanno identità. Il JVM può trattarle come primitivi e appiattirle in memoria: dentro array, dentro campi di oggetti, dentro registri CPU.
Ecco un esempio:
public value class PositiveInt {
private final int value;
public PositiveInt(int value) {
if (value <= 0) {
throw new IllegalArgumentException("must be positive: " + value);
}
this.value = value;
}
public int value() {
return value;
}
}
Il costruttore continua a validare. Ma il JVM può ora mettere il int direttamente dentro l’array o il register. 4 byte, senza header, senza indirezione.
Value Classes con più campi
Il vantaggio non si limita alle primitive. Un Coordinate che contiene Latitude e Longitude (entrambi double) può ora essere memorizzato come 16 byte consecutivi, senza puntatori.
Per applicazioni che elaborano dati geospaziali su larga scala, questo significa throughput molto più alto senza perdere la sicurezza dei tipi.
Tipi raffinati nel codice critico
Finora era difficile usare tipi che rappresentano regole di business nel codice ad alte prestazioni. Oggi, con Project Valhalla, è possibile.
Al NameOcean, per esempio, la registrazione di un domain comporta molte validazioni. Con value classes si può definire un DomainName o un Tld e li processare milioni di volte nel DNS pipeline con la sicurezza del tipo mantenuta ovunque. Il JVM li appiattisce e mantiene la performance.
La sicurezza a tempo di compilazione
Le value classes permettono anche di usare pattern di interfaccia che garantiscono la correttitudine a tempo di compilazione. Attraverso F-bounded generics, il compiler evita di confrontare un Probability con a Price. <|eos|>