Quelle est la surcharge du type Option de Rust?

Dans Rust, les références ne peuvent jamais être nulles. Par conséquent, si vous avez réellement besoin d’une valeur null, telle qu’une liste chaînée, vous utilisez le type Option :

 struct Element { value: i32, next: Option<Box>, } 

Combien de frais généraux y a-t-il à supporter en termes d’allocation de mémoire et d’étapes de déréférencement par rapport à un simple pointeur? Y a-t-il une “magie” dans le compilateur / runtime pour rendre Option gratuite ou moins coûteuse que si l’on implémentait Option par soi-même dans une bibliothèque non-core en utilisant la même construction enum ou en entourant le pointeur dans un vecteur ?

Oui, il existe une certaine magie du compilateur qui optimise Option sur un seul pointeur (la plupart du temps).

 use std::mem::size_of; macro_rules! show_size { (header) => ( println!("{:<22} {:>4} {}", "Type", "T", "Option"); ); ($t:ty) => ( println!("{:<22} {:4} {:4}", stringify!($t), size_of::<$t>(), size_of::>()) ) } fn main() { show_size!(header); show_size!(i32); show_size!(&i32); show_size!(Box); show_size!(&[i32]); show_size!(Vec); show_size!(Result<(), Box>); } 

Les tailles suivantes sont imprimées (sur une machine 64 bits, les pointeurs ont donc 8 octets):

 // As of Rust 1.22.1 Type T Option i32 4 8 &i32 8 8 Box 8 8 &[i32] 16 16 Vec 24 24 Result<(), Box> 8 16 

Notez que &i32 , Box , &[i32] , Vec utilisent tous l’optimisation du pointeur non nullable dans une Option !

Cette réponse est maintenant obsolète. le discriminant dans l’ Option est maintenant optimisé là où c’est possible. (Le rest des informations fournies est quand même intéressant)

Pour l’instant, un type Option occupe la même quantité d’espace que n’importe quel autre type enum . Je ne connais pas les détails, mais c’est certainement une sorte d’union discriminée.

La possibilité de modifier la représentation interne pour l’optimisation est envisagée par les développeurs de Rust.

Voici une discussion pertinente sur la liste de diffusion dev , publiée par Pasortingck Walton:

Je suis un peu réticent à m’engager dans une représentation particulière des enums, car il y a beaucoup de place pour l’optimisation du compilateur ici. Par exemple, nous pourrions vouloir réduire Option<~int> dans un pointeur nullable, nous pourrions vouloir réduire le Result<(),~str> dans une chaîne nullable, ou nous pourrions vouloir Either dans 1 mot, en supposant que les chaînes ne peuvent jamais occuper les 256 premiers octets de l’espace d’adressage. J’ai pensé pendant un moment que peut-être est-il préférable de dire que le modèle de bits de Rust enums n’est pas spécifié, pour nous donner le plus de place possible pour jouer avec les optimisations.