105 votes

Quels sont les frais généraux du type Option de Rust ?

En Rust, les références ne peuvent jamais être nulles, donc dans le cas où vous avez réellement besoin de null, comme une liste chaînée, vous utilisez l'attribut Option type :

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

Quelle est la surcharge en termes d'allocation de mémoire et d'étapes de déréférencement par rapport à un simple pointeur ? Existe-t-il une certaine "magie" dans le compilateur/le temps d'exécution pour faire de la Option sans frais, ou moins coûteux que si l'on devait mettre en œuvre Option par soi-même dans une bibliothèque non centrale utilisant la même enum ou en enveloppant le pointeur dans un vecteur ?

110voto

dbaupp Points 20762

Oui, il y a une certaine magie du compilateur qui optimise Option<ptr> à un seul pointeur (la plupart du temps).

use std::mem::size_of;

macro_rules! show_size {
    (header) => (
        println!("{:<22} {:>4}    {}", "Type", "T", "Option<T>");
    );
    ($t:ty) => (
        println!("{:<22} {:4} {:4}", stringify!($t), size_of::<$t>(), size_of::<Option<$t>>())
    )
}

fn main() {
    show_size!(header);
    show_size!(i32);
    show_size!(&i32);
    show_size!(Box<i32>);
    show_size!(&[i32]);
    show_size!(Vec<i32>);
    show_size!(Result<(), Box<i32>>);
}

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

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

Notez que &i32 , Box , &[i32] , Vec<i32> utilisent tous l'optimisation des pointeurs non nuls à l'intérieur d'un fichier Option !

4voto

barjak Points 4682

Cette réponse est maintenant obsolète ; le discriminant dans Option<T> est maintenant optimisé dans la mesure du possible. (Le reste des informations fournies reste néanmoins intéressant).

Pour l'instant, un Option occupe la même quantité d'espace que n'importe quel autre type de produit. enum type. Je ne connais pas les détails, mais il est certainement représenté comme une sorte de syndicat discriminé.

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

Voici un discussion pertinente sur la liste de diffusion "dev posté par Patrick Walton :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X