Оптимизирована ли опция до одного байта, когда T это позволяет?

#rust #optional

#Ржавчина #тип опции

Вопрос:

Предположим, у нас есть enum Foo { A, B, C } .

В этом случае Option<Foo> оптимизирована до одного байта?

Дополнительный вопрос: если да, то каковы пределы процесса оптимизации? Перечисления могут быть вложенными и содержать другие типы. Всегда ли компилятор способен вычислить максимальное количество комбинаций, а затем выбрать наименьшее представление?

Комментарии:

1. rustc, безусловно, знает размер вариантов перечисления. На самом деле, есть lint , который предупреждает, когда размер одного варианта значительно больше, чем у других. Но я не знаю, будет ли Option<Foo> в вашем вопросе оптимизирован до одного байта или нет.

2. Скорее всего, она оптимизирована для указателей типа Option<~T> .

3. Некоторое время назад был подан # 14540 о добавлении этой оптимизации в компилятор (поскольку это прекрасно разрешено языком).

Ответ №1:

Компилятор не очень умен, когда дело доходит до оптимизации расположения enum s для пространства. Учитывая:

 enum Option<T> { None, Some(T) }
enum Weird<T> { Nil, NotNil { x: int, y: T } }
enum Foo { A, B, C }
  

На самом деле компилятор рассматривает только один случай:

Option Подобное перечисление: один вариант, не содержащий данных («nullary»), один вариант, содержащий ровно одно значение datum. При использовании с указателем, который, как известно, никогда не равен null (в настоящее время только ссылки и Box<T> ), представление будет таким, как один указатель, null указывает нулевой вариант. В качестве особого случая Weird будет применена та же обработка, но значение y поля будет использоваться для определения, какой вариант представляет значение.

Помимо этого, доступно много-много возможных оптимизаций, но компилятор их пока не выполняет. В частности, ваш случай будет не представлен в виде одного байта. Для одного перечисления, не учитывая вложенный регистр, оно будет представлено как наименьшее возможное целое число.