web-dev-qa-db-fra.com

Quand faut-il utiliser inline dans Rust?

La rouille a un attribut "en ligne" qui peut être utilisé dans l'une de ces trois saveurs:

#[inline]

#[inline(always)]

#[inline(never)]

Quand devraient-ils être utilisés?

Dans la référence Rust référence, nous voyons ne section des attributs en ligne disant

Le compilateur inline automatiquement les fonctions basées sur l'heuristique interne. Des fonctions incorrectement alignées peuvent en fait ralentir le programme, il doit donc être utilisé avec précaution.

Dans le forum Rust internals, huon était également conservateur quant à la spécification en ligne .

Mais nous voyons tilisation considérable dans la source Rust, y compris la bibliothèque standard. De nombreux attributs en ligne sont ajoutés aux fonctions d'une ligne, ce qui devrait être facile pour les compilateurs à repérer et à optimiser par le biais d'heuristiques selon la référence. Ne sont-ils en fait pas nécessaires?

50
WiSaGaN

Une limitation du compilateur Rust Rust actuel est que si vous n'utilisez pas LTO (Link-Time Optimization), il n'inclura jamais une fonction non marquée #[inline] Dans les caisses. Rust utilise un modèle de compilation séparé similaire à C++ car l'implémentation LTO de LLVM ne s'adapte pas bien aux grands projets. Par conséquent, les petites fonctions exposées à d'autres caisses doivent être marquées à la main. Ce n'est pas une excellente situation, et il est probable qu'elle sera corrigée à l'avenir par une combinaison d'améliorations apportées à l'incrustation LTO et MIR.

#[inline(never)] est parfois utile pour le débogage (séparation d'un morceau de code qui ne fonctionne pas comme prévu). En théorie, il peut être utilisé pour l'analyse comparative, mais c'est généralement une mauvaise idée: la désactivation de l'inline n'empêche pas d'autres optimisations inter-procédurales comme la propagation constante. En termes de code normal, il peut réduire la taille du code si vous disposez d'une fonction d'assistance fréquemment utilisée qui n'est utilisée que pour la gestion des erreurs.

#[inline(always)] est généralement une mauvaise idée; si une fonction est suffisamment grande pour que le compilateur ne l'inline pas par défaut, elle est suffisamment grande pour que la surcharge de l'appel n'ait pas d'importance (et un alignement excessif augmente la pression du cache d'instructions). Il existe des exceptions, mais vous avez besoin de mesures des performances pour le justifier. Cet exemple est le genre de situation où cela vaut la peine d'être considéré. #[inline(always)] peut également être utilisé pour améliorer la qualité du code -O0, mais cela ne vaut généralement pas la peine de s'inquiéter.

43
Eli Friedman