Jak Valhalla zmienia grę: typy, wydajność i bezpieczeństwo domeny
Bezpieczeństwo typów spotyka wydajność: jak Project Valhalla zmienia reguły gry
Jeśli projektowałeś aplikacje w Javie z podejściem Domain-Driven Design, na pewno znasz ten dylemat. Chcesz stworzyć klasę PositiveInt, która gwarantuje, że wartość nigdy nie będzie ujemna. Kompilator powinien pilnować poprawności, a niepoprawne stany odrzucać.
Problem zaczyna się, gdy trafisz na krytyczną ścieżkę wykonywania. Procesor obsługujący miliony zdarzeń, gdzie każde niesie sekwencję typu PositiveInt. Nagle te bezpieczne typy stają się obciążeniem – 16 bajtów narzutu na wartość, tysiące alokacji na stercie, problemy z cache'em procesora. Dotychczasowa praktyka była prosta: bezpieczne typy zostawiamy przy granicach systemu, a wewnątrz gorących pętli wracamy do prymitywów.
Project Valhalla zamierza to zmienić.
Nadmiarowe narzuty starych wrapperów
Weźmy konkretny przykład. Klasa opakowująca pojedynczą wartość typu int zużywa na HotSpotie 16 bajtów – 12-bajtowy nagłówek obiektu plus 4 bajty na samą wartość (lub 8 bajtów z kompaktowymi nagłówkami w JDK 25+). Gdy umieścisz milion takich obiektów w tablicy, nie dostajesz wartości w linii. Dostajesz tylko tablicę wskaźników, które trzeba dereferencjonować.
Matematyka jest bezlitosna. Wrapper kosztuje cztery razy więcej pamięci niż chroniony przez niego prymityw. W przypadku losowego odczytu – każdy podgląd do pamięci oznacza wylecenie czegoś przydatnego z cache'a.
由此带来的结果是:安全类型只能在边界处发挥作用,而在内部处理数据时必须放弃它们。安全与性能之间存在明显的矛盾。
Nowe podejście: Value Classes
Project Valhalla, już dostępny w Java 27 Early Access, wprowadza słowo kluczowe value. W przeciwieństwie do zwykłych klas, które mają identity i zawsze alokują na stercie, value classes są identity-free. JVM może je spłaszczyć i traktować jak prymitywy – umieszczać bezpośrednio w tablicach, w polach innych obiektów, nawet w rejestrach procesora.
W praktyce wygląda to tak:
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;
}
}
Syntax jest zbliżony do regularnej klasy. Konstruktor działa. Validation pozostaje. Jednak JVM od tej anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen now anfen0