File: speed_matters.pod

package info (click to toggle)
libapache2-mod-perl2 2.0.9~1624218-2%2Bdeb8u2
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 11,912 kB
  • ctags: 4,588
  • sloc: perl: 95,064; ansic: 14,527; makefile: 49; sh: 18
file content (166 lines) | stat: -rw-r--r-- 3,633 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
=head1 NAME

Which Coding Technique is Faster

=head1 Description

This document tries to show more efficient coding styles by
benchmarking various styles.

WARNING: This doc is under construction

META: for now these are just unprocessed snippets from the mailing
list. Please help me to make these into useful essays.

=head1 backticks vs XS

META: unprocessed yet.

compare the difference of calling an
xsub that does _nothing_ vs. a backticked program that does _nothing_.

  /* file:test.c */
  int main(int argc, char **argv, char **env)
  {
      return 1;
  }

  /* file:TickTest.xs */
  #include "EXTERN.h"
  #include "perl.h"
  #include "XSUB.h"
  
  MODULE = TickTest		PACKAGE = TickTest		
  
  void
  foo()
  
  CODE:

  # file:test.pl
  use blib;
  use TickTest ();
  
  use Benchmark;
  
  timethese(100_000, {
      backtick => sub { `./test` },
      xs => sub { TickTest::foo() },
  });

Results:

  Benchmark: timing 100000 iterations of backtick, xs...
    backtick: 292 wallclock secs (18.68 usr 43.93 sys + 142.43 cusr 84.00 csys = 289.04 CPU) @ 1597.19/s (n=100000)
          xs: -1 wallclock secs ( 0.25 usr +  0.00 sys =  0.25 CPU) @ 400000.00/s (n=100000)
              (warning: too few iterations for a reliable count)


=head1 sv_catpvn vs. fprintf

META: unprocessed yet.

and what i'm trying to say is that if both the xs code and external
program are doing the same thing, xs will be heaps faster than backticking
a program.  your xsub and external program are not doing the same thing.

i'm guessing part of the difference in your code is due to fprintf having
a pre-allocated buffer, whereas the SV's SvPVX has not been pre-allocated
and gets realloc-ed each time you call sv_catpv.  have a look at the code
below, fprintf is faster than sv_catpvn, but if the SvPVX is preallocated,
sv_catpvn becomes faster than fprintf:

  timethese(1_000, {
      fprintf   => sub { TickTest::fprintf() },
      svcat     => sub { TickTest::svcat() },
      svcat_pre => sub { TickTest::svcat_pre() },
  });
  
  Benchmark: timing 1000 iterations of fprintf, svcat, svcat_pre...
     fprintf:  9 wallclock secs ( 8.72 usr +  0.00 sys =  8.72 CPU) @ 114.68/s (n=1000)
       svcat: 13 wallclock secs (12.82 usr +  0.00 sys = 12.82 CPU) @ 78.00/s (n=1000)
   svcat_pre:  2 wallclock secs ( 2.75 usr +  0.00 sys =  2.75 CPU) @ 363.64/s (n=1000)
  
  #include "EXTERN.h"
  #include "perl.h"
  #include "XSUB.h"
  
  static FILE *devnull;
  
  MODULE = TickTest		PACKAGE = TickTest		
  
  BOOT:
  devnull = fopen("/dev/null", "w");
  
  void
  fprintf()
  
      CODE:
      {
          int i;
          char buffer[8292];
  
          for (i=0; i<sizeof(buffer); i++) {
              fprintf(devnull, "a");
          }
      }
  
  void
  svcat()
  
      CODE:
      {
          int i;
          char buffer[8292];
          SV *sv = newSV(0);
  
          for (i=0; i<sizeof(buffer); i++) {
              sv_catpvn(sv, "a", 1);
          }
  
          SvREFCNT_dec(sv);
      }
  
  void
  svcat_pre()
  
      CODE:
      {
          int i;
          char buffer[8292];
          SV *sv = newSV(sizeof(buffer)+1);
  
          for (i=0; i<sizeof(buffer); i++) {
              sv_catpvn(sv, "a", 1);
          }
  
          SvREFCNT_dec(sv);
      }


=head1 Maintainers

Maintainer is the person(s) you should contact with updates,
corrections and patches.

Stas Bekman [http://stason.org/]

=head1 Authors

=over

=item *

Stas Bekman [http://stason.org/]

=item * 

Doug MacEachern E<lt>dougm (at) covalent.netE<gt>

=back

Only the major authors are listed above. For contributors see the
Changes file.


=cut