File Coverage

blib/lib/Devel/GoFaster.pm
Criterion Covered Total %
statement 13 21 61.9
branch 1 8 12.5
condition 0 6 0.0
subroutine 5 7 71.4
pod n/a
total 19 42 45.2


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Devel::GoFaster - optimise executable Perl ops
4              
5             =head1 SYNOPSIS
6              
7             use Devel::GoFaster;
8              
9             use Devel::GoFaster "global";
10              
11             =head1 DESCRIPTION
12              
13             This module implements some optimisations in compiled Perl code, which
14             should make it run slightly faster without visibly affecting behaviour.
15             The optimisations are applied at the peephole optimisation step,
16             augmenting Perl's built-in optimisations.
17              
18             Code to be made faster does not need to be written in any special way;
19             this module can generally be applied to code that was not written with it
20             in mind. However, to help with situations where the op munging causes
21             trouble (such as with the deparser), there is some selectivity in which
22             code gets the optimisations. Whether to apply these optimisations is
23             decided for each subroutine as a whole: it cannot be enabled or disabled
24             for just part of a subroutine. There is a global control, defaulting
25             to off, and lexically-scoped local control which takes precedence over
26             the global control.
27              
28             Because the optimisations are applied in the peephole optimiser, not
29             affecting primary compilation, they are invisible to most modules that
30             muck around with op trees during compilation. So this module should play
31             nicely with modules that use custom ops and the like. However, anything
32             that examines the ops of a complete compiled subroutine is liable to see
33             the non-standard optimised ops from this module, and may have a problem.
34             In particular, the deparser can't correctly deparse code that has been
35             affected by this module. If such problems affect a particular subroutine,
36             the lexical control can be used to disable non-standard optimisation of
37             that subroutine alone.
38              
39             This module tries quite hard to not visibly fail, so that it should be
40             generally safe to use its pragmata. If circumstances make it impossible
41             to apply optimisations that would sometimes be available, the module
42             will silently leave code unoptimised. In particular, because all the
43             optimisations are necessarily implemented using XS code, on any system
44             that can't build or load XS modules this module's pragmata effectively
45             become no-ops. No particular optimisations are guaranteed by invoking
46             this module.
47              
48             =cut
49              
50             package Devel::GoFaster;
51              
52 5     5   492398 { use 5.006; }
  5         28  
53 5     5   2187 use Lexical::SealRequireHints 0.008;
  5         5285  
  5         41  
54 5     5   200 use warnings;
  5         19  
  5         218  
55 5     5   40 use strict;
  5         15  
  5         1842  
56              
57             our $VERSION = "0.001";
58              
59             eval { local $SIG{__DIE__};
60             require XSLoader;
61             XSLoader::load("Devel::GoFaster", $VERSION);
62             };
63              
64             our $global_on = 0;
65              
66             sub _croak {
67 0     0   0 require Carp;
68 0         0 goto &Carp::croak;
69             }
70              
71             =head1 PRAGMATA
72              
73             =over
74              
75             =item use Devel::GoFaster
76              
77             Locally enable the optimisations of this module. Subroutines compiled in
78             the lexical scope of this pragma will get the non-standard optimisations,
79             regardless of the global pragma state.
80              
81             =item no Devel::GoFaster
82              
83             Locally disable the optimisations of this module. Subroutines compiled
84             in the lexical scope of this pragma will not get the non-standard
85             optimisations, regardless of the global pragma state.
86              
87             =item use Devel::GoFaster "global"
88              
89             Globally enable the optimisations of this module. Subroutines compiled
90             after this pragma has been encountered will get the non-standard
91             optimisations, except where locally overridden.
92              
93             =item no Devel::GoFaster "global"
94              
95             Globally disable the optimisations of this module (which is the default
96             state). Subroutines compiled after this pragma has been encountered will
97             not get the non-standard optimisations, except where locally overridden.
98              
99             =back
100              
101             =cut
102              
103             sub import {
104 5 50 0 5   63 if(@_ == 1) {
    0          
105 5         11248 $^H{"Devel::GoFaster/on"} = 1;
106             } elsif(@_ == 2 && $_[1] eq "global") {
107 0           $global_on = 1;
108             } else {
109 0           _croak "bad arguments for $_[0] import";
110             }
111             }
112              
113             sub unimport {
114 0 0 0 0     if(@_ == 1) {
    0          
115 0           $^H{"Devel::GoFaster/on"} = 0;
116             } elsif(@_ == 2 && $_[1] eq "global") {
117 0           $global_on = 0;
118             } else {
119 0           _croak "bad arguments for $_[0] unimport";
120             }
121             }
122              
123             =head1 BUGS
124              
125             As noted L, this module is liable to break anything
126             that examines the ops of a complete compiled subroutine, such as the
127             deparser.
128              
129             =head1 AUTHOR
130              
131             Andrew Main (Zefram)
132              
133             =head1 COPYRIGHT
134              
135             Copyright (C) 2015, 2017 Andrew Main (Zefram)
136              
137             =head1 LICENSE
138              
139             This module is free software; you can redistribute it and/or modify it
140             under the same terms as Perl itself.
141              
142             =cut
143              
144             1;