2010-11-02 34 views
8

Je lis Code Complete 2, et l'un des points mentionnés concerne la création de sous-programmes, même pour des opérations qui semblent trop simples pour avoir leurs propres sous-programmes, et comment cela peut être utile. Je sais que je peux inline functions in C and C++ en utilisant le mot-clé inline. Mais je n'ai jamais trouvé un moyen d'intégrer les sous-routines dans Perl.Comment puis-je intégrer des sous-routines Perl?

Existe-t-il un moyen de dire à l'interpréteur Perl de mettre en ligne les appels de sous-programmes (ou pourquoi pas)?

+0

Vous devriez toujours suivre les conseils, même si les possibilités d'inlining peuvent sembler plus limitées dans Perl. –

Répondre

21

Des sous-programmes constants, c'est-à-dire des sous-programmes avec un prototype vide et une valeur de retour constante, sont en ligne. Voilà comment la constant pragma définit les constantes:

sub five() { 5 } 

serait inline si on voit avant sa première utilisation.

Dans le cas contraire, Perl permet de redéfinir dynamiquement les sous-programmes lors de l'exécution, de sorte que le mode inline ne convient pas.

Pour les sous-programmes qui retournent toujours la même valeur avec les mêmes entrées, vous pouvez utiliser memoization.

Chapter 13 of Programming Perl fournit des informations sur les étapes d'optimisation prises par perl.

Ceci est appelé pliage constant. Le pliage constant n'est pas limité à des cas simples tels que le passage de 2 ** 10 à 1024 au moment de la compilation. Il résout également les appels de fonction - à la fois les sous-programmes intégrés et les sous-programmes déclarés par l'utilisateur qui satisfont aux critères de la section «Fonctions de Constant Inline» du Chapitre 6, Sous-programmes. Rappelant la connaissance notoire des compilateurs FORTRAN de leurs propres fonctions intrinsèques, Perl sait également lequel de ses propres built-ins à appeler pendant la compilation. C'est pourquoi si vous essayez de prendre le log de 0.0 ou le sqrt d'une constante négative, vous encourrez une erreur de compilation, pas une erreur d'exécution, et l'interpréteur n'est jamais exécuté du tout.

Voir également perldoc perlguts.

Vous pouvez voir l'effet de vous-pliage constant:

#!/usr/bin/perl 

use strict; use warnings; 

sub log_ok() { 1 } 

if (log_ok) { 
    warn "log ok\n"; 
} 
perl -MO=Deparse t.pl

Sortie:

sub log_ok() { 1 } 
use warnings; 
use strict 'refs'; 
do { 
    warn "log ok\n" 
}; 
t.pl syntax OK

Ici, le pliage constant a conduit au remplacement du bloc if avec un bloc do parce que le compilateur savait que log_ok retournerait toujours une vraie valeur. D'autre part, avec:

#!/usr/bin/perl 

use strict; use warnings; 

sub log_ok() { 0.5 > rand } 

if (log_ok) { 
    warn "log ok\n"; 
} 

sortie Deparse:

sub log_ok() { 
    use warnings; 
    use strict 'refs'; 
    0.5 > rand; 
} 
use warnings; 
use strict 'refs'; 
if (log_ok) { 
    warn "log ok\n"; 
} 
t.pl syntax OK

Un compilateur C aurait remplacé le if (log_ok) avec if (0.5 > rand). perl ne fait pas cela.

5

Perl ne permet que des fonctions constantes en ligne.De perldoc perlsub:

fonctions avec un prototype de() sont candidats potentiels pour inline. Si le résultat après optimisation et pliage constante est soit un ou un scalaire de portée lexicales constante qui a aucune autre référence, alors il sera utilisé à la place des appels de fonction effectués sans &.

3

Je n'ai pas essayé toutes ces choses, mais si vous avez le temps, vous pouvez essayer

  1. Macro
  2. macro
  3. ou même Filter::Macro

Ils » Re tous les filtres de source, vous devrez donc vérifier votre retour sur investissement dans la performance. Le dernier a en effet un avis sur cpanratings. (Ignorer la tentative de Dan Dascalescu pour réguler le module Perl « espace aérien ».)

-En fait, le dernier Filter::Macro utilise Filter::Simple::Compile (qui utilise à son tour Module::Compile) pour compiler les routines, donc ce pourrait effectuer ci-dessus les autres méthodes de filtrage de source. Mais les standard caveats on source filters s'appliquent.

1

La vitesse ne devrait probablement pas être prise en compte lors de l'écriture de Perl. Allez-y et faites fonctionner les choses. Si le profilage montre plus tard que vous passez beaucoup de temps dans une fonction simple en raison de l'appel beaucoup, puis en ligne cette fonction vous-même.

+0

;) L'optimisation prématurée est la racine de tout mal - a déclaré Donald E. Knuth, et à juste titre. – Jinxed