web-dev-qa-db-fra.com

Dans Julia, pourquoi @printf est-il une macro au lieu d'une fonction?

Dans Julia, la syntaxe pour imprimer une chaîne formatée est la suivante:

@printf("Hello %d\n", 5)

Pourquoi est-ce @printf une macro au lieu d'une fonction? Est-ce pour pouvoir accepter un nombre variable d'arguments?

63
Ben Hamner

Prendre un nombre variable d'arguments n'est pas un problème pour les fonctions normales de Julia [ 1 ]. @printf est une macro qui permet d'analyser et d'interpréter la chaîne de format au moment de la compilation et de générer du code personnalisé pour cette chaîne de format spécifique. Les gens peuvent ne pas se rendre compte que la fonction printf de C ré-analyse et ré-interprète la chaîne de format chaque fois que vous appelez printf. Le fait qu'il soit aussi rapide qu'il est représente un miracle mineur de programmation de pointeurs insensée. Sérieusement, regardez simplement l'implémentation printf de votre libc la plus proche. C'est complètement fou.

Julia utilise une approche différente: @printf est une macro qui traduit les chaînes de format en un code efficace spécifique à cette spécification de format. Si vous y réfléchissez, une chaîne de format de style printf est vraiment juste un moyen d'exprimer une fonction qui prend un nombre et un type d'arguments fixes et les imprime d'une manière particulière. Notez que j'ai dit que la chaîne de format est une fonction, pas printf elle-même, qui est conceptuellement un générateur de fonctions, transformant les formats en formateurs. Le fait que tout cela soit entassé dans une fonction d'exécution en C est un peu un décalage car c'est la seule option raisonnable en C. En fait, à cause de cela, jusqu'à très récemment, il était assez facile de se tirer dessus dans le pied en passant le mauvais nombre ou type d'arguments au printf de C. C'est encore mieux maintenant car les compilateurs ont été spécialement conçus pour comprendre la sémantique des formats printf.

En théorie, Julia @printf peut être fait plus rapidement que C car il génère du code personnalisé, mais en pratique, j'ai eu assez de mal à faire correspondre C, sans parler de le battre. Mais je pense que cela est dû à la conception actuelle de notre système d'E/S et à la façon dont je l'utilise, et non à une limitation inhérente. Les éléments d'E/S doivent cependant être révisés, et lorsque cela se produit, nous pourrions en fait battre C lors de l'impression formatée en tirant parti du fait que @printf est une macro.

101
StefanKarpinski

C'est pour la performance. La macro printf prend une chaîne de format constant (par exemple. "Hello %d\n") et génère un code optimisé pour cette chaîne.

5
ivarne