Valhalla меняет правила: домены, типы и скорость в одном флаконе
Type Safety Meets Performance: Project Valhalla меняет правила
Когда вы строите доменную модель в Java, часто возникает конфликт. Хотите создать тип PositiveInt, который гарантирует положительное значение. Хотите, чтобы компилятор отлавливал ошибки ещё на этапе сборки. Но стоит дойти до горячего участка кода — и всё ломается.
Миллионы событий, каждое с номером последовательности. Каждый PositiveInt тянет за собой 16 байт заголовка объекта, аллокации в куче и промахи по кэшу. Поэтому годами работали по схеме: проверяем типы на входе, а внутри уже используем примитивы. Безопасность отходит на второй план.
Project Valhalla меняет этот компромисс.
Проблема: overhead от обёрток
Возьмём простой пример. Класс-обёртка над int занимает 16 байт на HotSpot — 12 байт заголовка плюс само значение. При размещении миллиона таких объектов в массиве вы получаете не данные, а ссылки на них. Каждый доступ — это разыменование указателя и потенциальный промах по кэшу.
Результат предсказуем. Обёртка съедает в четыре раза больше памяти, чем защищаемый ею примитив. Данные разбросаны по куче, и горячие пути обработки становятся медленнее.
Value Classes: безопасность без потерь
Теперь в Java 27 Early Access появился value модификатор. Value-классы лишены идентичности. JVM может упаковать их в регистры, вставить прямо в массив или поле объекта — без заголовка и без ссылки.
Вот как выглядит такой класс:
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;
}
}
Конструктор остаётся прежним. Валидация работает. Тип гарантирует, что überall там, где встречается PositiveInt, значение действительно положительное. Но JVM уже не обязан создавать объект на куче. Он может flatten их до 4 байт — прямо как primitive.
Многоуровневая безопасность
Это особенно интересно для типов с несколькими полями. Например, Coordinate содержит Latitude и Longitude, каждый из них backed by double. В обычном класах это три уровня ссылочных объектов. В value-классах оба double упакуют в 16 байт без указателей и промахов по кэшу.
Для приложений, которые обрабатывают геоданные — например, погодные модели или отслеживание позиций — это означает значительный gain в пропускной способности без牺牲ей типа.
Применение в практике: доменные типы
В контексте регистраций доменов и DNS можно применить value-классы прямо на уровне обработки данных. Теперь можно создать DomainName и Tld, которые проверяют свои значения при создании:
public value class DomainName {
private final String value;
public DomainName(String value) {
if (!isValidDomain(value)) {
throw new IllegalArgumentException("Invalid domain: " + value);
}
this.value = value;
}
}
Вместо string или int можно теперь использовать типы, которые garanty безопасность всюду в конвейере. Пропускная способностью не жертвуют — потому что JVM flatten их до размеру primitives.
Тип-система и правильность
Value-классы не только для performance. Они также позволяют реализовать compile-time проверку. Например, с помощью F-bounded generics можно гарантировать, что Probability не будет случайно сравниваться с Price. Это было всегда возможное, но практически нереализуемо из-за overhead.
Value-классы делают это praktisch.
Что это значит для архитектуры
В cloud-приложениях, особенно на инфраструктуре с AI-driven оптимизацией, value-классы позволяют:
- Валидацию на границах не жертвовать под performance
- Тип-систему использовать не только на входе, но и внутри кодов
- Domain-driven design не оставлять только теоретической, а сделать практично
Теперь можно encode business rules в типах и оставить JVM заботиться о скорости. Не нужно выбирать между correctness и speed.
Вперёд
Project Valhalla ещё в preview, но тенденция уже ясна. Когда value-классы будут стабильны в LTS-релизах, они станут стандартным способом построения архитектур.
Если вы сейчас строите системы, начните думать, где сейчас вы используйте raw primitives после валидации. Там и будут применены value-классы.