Beef, un nouveau langage de programmation orienté performance

https://programmation.developpez.com/actu/289936/Beef-un-nouveau-langage-de-programmation-oriente-performance-espere-fournir-une-experience-de-developpement-fluide-et-agreable-pour-les-applications-en-temps-reel-hautes-performances/

Beef est un langage de programmation compilé axé sur les performances. La syntaxe et la conception de la bibliothèque principale dérivent de C#, mais il existe de nombreuses différences sémantiques en raison d’objectifs de conception différents. Le langage a été développé en même temps que son environnement EDI et une attention particulière a été portée à la satisfaction globale du développement d’applications Beef. Le public visé est le développeur axé sur les performances qui apprécie la simplicité, la lisibilité du code, l’itération de développement rapide et un bon débogage.

L’objectif principal de Beef est de fournir une expérience de développement fluide et agréable pour les applications en temps réel hautes performances telles que les jeux vidéo, avec des fonctionnalités de bas niveau qui le rendent adapté au développement de moteur, combiné à une ergonomie de haut niveau adaptée au développement de code de jeu.

Le langage a d’abord été publié le 29 septembre en version 0.42.0 et a reçu une mise à jour le 31 décembre qui a apporté :
une amélioration des capacités de compilation croisée ;
un ajout de cibles de build macOS, iOS et Android ;
des optimisations pour le GC d’allocateur de débogage ;
une prise en charge supplémentaire des contraintes de l’opérateur ;
un ajout d’attributs de remplacement d’alignement d’allocations ;
une prise en charge étendue de la liste de capture lambda pour inclure des noms de variables spécifiques ;
des capacités annulables améliorées, y compris les opérateurs.

Beef permettrait de mélanger en toute sécurité différents niveaux d’optimisation sur un niveau par type ou par méthode, permettant au code critique de performance d’être exécuté à la vitesse maximale sans affecter la débogabilité du reste de l’application.

La gestion de la mémoire dans Beef est manuelle et inclut un support de première classe pour les allocateurs personnalisés. Des précautions ont été prises pour réduire le fardeau de la gestion manuelle de la mémoire grâce à l’ergonomie du langage et aux sécurités d’exécution - Beef pourrait détecter les fuites de mémoire en temps réel et offrirait une protection garantie contre les erreurs d’utilisation après libération et de double suppression. Comme avec la plupart des fonctions de sécurité de Beef, ces sécurités de mémoire peuvent être désactivées dans les versions pour une performance maximale.

Le Beef IDE prend en charge des fonctionnalités de productivité telles que la saisie semi-automatique, les correctifs, le reformatage, les outils de refactorisation, l’inspection de type, la compilation de code d’exécution (échange de code à chaud) et un profileur intégré. Le débogueur polyvalent de l’EDI serait capable de déboguer des applications natives écrites dans n’importe quel langage, et est destiné à être un débogueur autonome complet, même pour les développeurs C / C ++ purs qui souhaitent une alternative au débogage de Visual Studio.

Modèle de compilation

Le contexte de compilation Beef est un espace de travail, qui se compose de plusieurs projets. Un projet peut être soit une bibliothèque, soit produire un binaire tel qu’un exécutable ou une DLL. Les sources sont analysées, transmises via un préprocesseur limité, compilées et une collection de fichiers objet est créée pour les types et méthodes référencés, qui sont ensuite liés aux binaires cibles. Le modèle de compilation à l’échelle de l’espace de travail permet aux paramètres par espace de travail d’affecter les compilations de groupes spécifiques de méthodes ou de types, en modifiant le préprocesseur et les paramètres de compilation (par exemple: niveau d’optimisation) du code même lorsqu’il est contenu dans des bibliothèques tierces référencées.

La compilation incrémentielle est prise en charge, avec un graphe de dépendances reconstruisant uniquement les objets potentiellement affectés et avec un cache principal pour éviter de reconstruire des objets sans modifications fonctionnelles. La compilation incrémentielle peut être désactivée pour créer des versions reproductibles.

Beef prend en charge plusieurs backends de compilateur, y compris LLVM et un backend de « débogage amélioré » (Og +) personnalisé qui effectue certaines optimisations de code qui n’ont pas d’incidence négative sur le débogage et a quelques améliorations dans les informations de débogage émises sur LLVM.

Plusieurs éditeurs de liens sont pris en charge, y compris les éditeurs de liens système et l’éditeur de liens LLVM qui peuvent être utilisés pour les générations optimisées au moment de la liaison (LLVM LTO / ThinLTO).

Fonctionnalités de sécurité

Beef prend en charge une variété de fonctionnalités de sécurité optionnelles, dont beaucoup peuvent être désactivées pour des groupes de code spécifiés pour les versions de « sécurité mixte ». Par défaut, les vérifications suivantes sont activées pour tout le code dans les versions de débogage et elles sont désactivées dans les versions de version.

Vérification des limites

La vérification des limites est implémentée dans la bibliothèque standard pour les tableaux, les collections, les étendues et les chaînes. Dans de nombreux cas, ceux-ci sont implémentés en ayant un accesseur [Checked] qui effectue des vérifications des limites et un autre accesseur [Unchecked] qui ne vérifie pas les limites. Cela permet de vérifier les limites sur le site d’appel plutôt que d’être déterminé à l’échelle de la collection.

Vérification dynamique de la distribution

Les transtypages d’objets explicites vers un type dérivé non valide seront interceptés lors de l’exécution.

Fuites de mémoire

Les fuites peuvent être détectées en temps réel avec le gestionnaire de mémoire de débogage. La mémoire accessible sera tracée en continu lors de l’exécution et la mémoire qui n’est plus accessible, mais qui n’a pas été correctement libérée sera immédiatement signalée comme une fuite, avec l’emplacement du code où l’allocation s’est produite. La profondeur de trace de pile pour ce suivi d’allocation est réglable.

Double libération / utilisation après libération

Lorsque le gestionnaire de mémoire de débogage est activé, les objets dont la libération a été demandée seront marqués comme « libérés », mais la mémoire ne sera pas récupérée physiquement tant qu’il n’y aura plus de références à la mémoire qu’elle occupe. Toute tentative d’utilisation de la mémoire après qu’elle a été marquée comme libérée est garantie d’échouer immédiatement, et la valeur de cet objet libéré et sa trace de pile d’allocations seront valides et visibles dans le débogueur.

Gestion de la mémoire

Allocation de la mémoire

Les allocations peuvent être placées sur la pile, l’allocateur global ou un allocateur personnalisé. Les allocations de pile utilisent le mot clé «scope», qui peut spécifier une étendue de l’étendue actuelle (c.-à-d.: Bloc de code) à l’étendue de la méthode entière (même dans une boucle).

Allocateur global

L’allocateur global est sélectionné pour chaque espace de travail. Par défaut, les allocateurs CRT malloc / free sont utilisés, mais n’importe quel allocateur global de style C peut être utilisé, comme TCMalloc ou JEMalloc. De plus, Beef contient un allocateur de débogage spécial qui permet des fonctionnalités telles que la vérification des fuites en temps réel et la compilation à chaud.

Les allocations Beef sont de style C en ce sens qu’elles ne sont pas délocalisables et qu’il n’y a pas de garbage collector.

Libérer de la mémoire

Les allocations de portée sont automatiquement débloquées à la fin de scope, mais les allocations manuelles doivent être débloquées manuellement avec le mot-clé «delete». De même que pour les allocations d’allocateurs personnalisées, la suppression peut spécifier une cible d’allocateur personnalisée pour libérer de la mémoire à partir d’allocateurs personnalisés.