IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

La version 3.2 du langage de programmation Ruby est disponible
Elle apporte de nombreuses fonctionnalités et améliore les performances

Le , par Bruno

23PARTAGES

2  0 
Comme à son habitude, en guise de cadeau de Noël pour les développeurs Ruby, l’équipe de développement du langage de programmation a annoncé le 25 décembre la sortie de la version 3.2 de langage de programmation. Dans cette nouvelle version du langage multiparadigme, on trouve un algorithme de correspondance Regexp amélioré et le support de WebAssembly basé sur WASI

Support de WebAssembly basé sur WASI

Il s'agit d'un portage initial du support WebAssembly basé sur WASI. Cela permet à un binaire CRuby d'être disponible sur un navigateur Web, un environnement Serverless Edge, ou d'autres types d'embedders WebAssembly/WASI. Actuellement, ce portage passe les suites de tests de base et d'amorçage n'utilisant pas l'API Thread.


Intégration

WebAssembly (Wasm) a été introduit à l'origine pour exécuter des programmes rapidement et en toute sécurité dans les navigateurs web. Mais son objectif - exécuter des programmes efficacement et en toute sécurité dans divers environnements - est recherché depuis longtemps non seulement pour le web mais aussi par des applications générales. WASI (The WebAssembly System Interface) est conçu pour de tels cas d'utilisation. Bien que ces applications aient besoin de communiquer avec les systèmes d'exploitation, WebAssembly fonctionne sur une machine virtuelle qui n'avait pas d'interface système. La WASI la normalise.

La prise en charge de WebAssembly/WASI dans Ruby vise à tirer parti de ces projets. Il permet aux développeurs Ruby d'écrire des applications qui fonctionnent sur ces plateformes.

Cas d'utilisation

Ce support encourage les développeurs à utiliser CRuby dans un environnement WebAssembly. Un exemple d'utilisation est le support CRuby du playground TryRuby. Vous pouvez maintenant essayer CRuby original dans votre navigateur Web.

Points techniques

Le WASI d'aujourd'hui et WebAssembly lui-même manquent de certaines fonctionnalités pour mettre en œuvre Fiber, exception, et GC parce qu'il est encore en cours de développement, et aussi pour des raisons de sécurité. CRuby comble donc ce manque en utilisant Asyncify, qui est une technique de transformation binaire pour contrôler l'exécution en userland.

En outre, l’équipe Ruby a construit un VFS au-dessus de WASI afin de pouvoir facilement regrouper les applications Ruby dans un seul fichier .wasm. Cela rend la distribution des applications Ruby un peu plus facile.

Le YJIT prêt pour la production

YJIT est un JIT Ruby léger et minimaliste construit dans CRuby. Il compile le code en utilisant une architecture BBV (Basic Block Versioning). Le cas d'utilisation visé est celui des serveurs exécutant Ruby on Rails, un domaine où MJIT n'a pas encore réussi à fournir des accélérations. YJIT est actuellement pris en charge pour macOS et Linux sur les processeurs x86-64 et arm64/aarch64. Ce projet est open source et tombe sous la même licence que CRuby.

  • YJIT n'est plus expérimental ;
    • Il a été testé sur des charges de travail de production pendant plus d'un an et s'est avéré très stable ;
  • Il prend désormais en charge les processeurs x86-64 et arm64/aarch64 sur Linux, MacOS, BSD et d'autres plateformes UNIX ;
    • Cette version apporte le support pour Apple M1/M2, AWS Graviton, Raspberry Pi 4 et plus ;
  • La construction de YJIT nécessite maintenant Rust 1.58.0+ ;
    • Afin de s'assurer que CRuby est construit avec YJIT, veuillez installer rustc >= 1.58.0 avant d'exécuter le script ./configure ;
  • La version 3.2 de YJIT est plus rapide que la version 3.1, et a environ un tiers de moins de surcharge mémoire.
    • Globalement, YJIT est 41% plus rapide (moyenne géométrique) que l'interpréteur Ruby sur yjit-bench ;
    • La mémoire physique pour le code JIT est allouée paresseusement. Contrairement à Ruby 3.1, le RSS d'un processus Ruby est minimisé car les pages de mémoire virtuelle allouées par --yjit-exec-mem-size ne seront pas mappées en pages de mémoire physique avant d'être effectivement utilisées par le code JIT ;
    • Introduire la GC du code qui libère toutes les pages de code lorsque la consommation de mémoire par le code JIT atteint --yjit-exec-mem-size ;
    • RubyVM::YJIT.runtime_stats renvoie des mesures de Code GC en plus des clés inline_code_size et outlined_code_size existantes : code_gc_count, live_page_count, freed_page_count, et freed_code_size.
  • La plupart des statistiques produites par RubyVM::YJIT.runtime_stats sont maintenant disponibles dans les builds de version ;.
  • Il suffit d'exécuter ruby avec --yjit-stats pour calculer et afficher les statistiques (ce qui entraîne une surcharge de temps d'exécution) ;
  • YJIT est désormais optimisé pour tirer parti des formes des objets.
  • Profiter de l'invalidation des constantes à grain fin pour invalider moins de code lors de la définition de nouvelles constantes. [Fonctionnalité n°18589]
  • La valeur par défaut de --yjit-exec-mem-size est passée à 64 (MiB).
  • Le seuil d'appel par défaut --yjit-call-threshold est modifié à 30.

Améliorations de Regexp contre ReDoS

Il est connu que la correspondance des expressions régulières peut prendre un temps considérable. Si le code tente de faire correspondre une Regexp potentiellement inefficace avec une entrée non fiable, un attaquant peut l'exploiter pour un déni de service efficace (appelé expression régulière DoS, ou ReDoS). L’équipe Ruby a introduit deux améliorations qui atténuent considérablement les ReDoS.

Algorithme de correspondance Regexp amélioré

Depuis Ruby 3.2, l'algorithme de correspondance de Regexp a été grandement amélioré en utilisant une technique de mémorisation.

# This match takes 10 sec. in Ruby 3.1, and 0.003 sec. in Ruby 3.2
/^a*b?a*$/ =~ "a" * 50000 + "x"



L'algorithme de correspondance amélioré permet de réaliser la plupart des correspondances Regexp (environ 90 %) en temps linéaire.
Cette optimisation peut consommer de la mémoire proportionnellement à la longueur de l'entrée pour chaque correspondance. Une correspondance Regexp normale devrait consommer au maximum 10 fois plus de mémoire que la longueur de l'entrée.

Délai d'attente pour les Regexp

L'optimisation ci-dessus ne peut pas être appliquée à certains types d'expressions régulières, comme celles qui incluent des fonctionnalités avancées (par exemple, des références arrière ou des recherches), ou qui comportent un nombre fixe important de répétitions. En guise de mesure de repli, une fonction de délai d'attente pour les correspondances Regexp est également introduite.
Regexp.timeout = 1.0

/^a*b?a*()\1$/ =~ "a" * 50000 + "x"
#=> Regexp::TimeoutError is raised in one second

Notons que Regexp.timeout est une configuration globale. Pour utiliser des paramètres de délai différents pour certaines Regexp spéciales, il est possible d’utiliser le mot clé timeout pour Regexp.new.
Regexp.timeout = 1.0

# This regexp has no timeout
long_time_re = Regexp.new('^a*b?a*()\1$', timeout: Float::INFINITY)

long_time_re =~ "a" * 50000 + "x" # never interrupted

Autres nouveautés notables

SyntaxSuggest

La fonctionnalité de syntax_suggest (anciennement dead_end) est intégrée à Ruby. Elle aide à trouver la position d'erreurs telles que des fins manquantes ou superflues, afin de remettre en route plus rapidement, comme dans l'exemple suivant :
Unmatched `end', missing keyword (`do', `def`, `if`, etc.) ?

1 class Dog
> 2 defbark
> 3 end
4 end


ErrorHighlight

Il indique maintenant le ou les arguments pertinents pour TypeError et ArgumentError.
test.rb:2:in `+': nil can't be coerced into Integer (TypeError)

sum = ary[0] + ary[1]
^^^^^^


Source : Ruby

Et vous ?

Avez-vous testé la nouvelle version de Ruby ?

Quel est votre avis sur les nouvelles fonctionnalités et améliorations apportées ?

Voir aussi :

Ruby 2.6 est disponible en version stable, avec un nouveau compilateur JIT en mode expérimental et un nouveau module pour analyser du code Ruby

Ruby 2.7 est disponible en version stable, avec l'ajout du filtrage par motif, d'une nouvelle méthode pour compacter le tas et plusieurs améliorations de performance non négligeables

Une erreur dans cette actualité ? Signalez-nous-la !