4
4
5
5
= SUBTITLE Measuring and improving run-time or compile-time performance
6
6
7
- B < Make sure you're not wasting time on the wrong code > : start by identifying your
8
- L < "critical 3%"|https://en.wikiquote.org/wiki/Donald_Knuth > by profiling your code (explained on this page).
7
+ In computer science, "performance" has many sub-topics such as
8
+ L < throughput|https://en.wikipedia.org/wiki/Throughput > ,
9
+ L < latency|https://en.wikipedia.org/wiki/Latency_(engineering) > ,
10
+ or L < garbage collection| > .
9
11
10
- If you decide to talk about a performance problem, please first prepare a one-liner and/or public gist
11
- that illustrates the problem.
12
- Also, let folk know if you are using Perl 6 in your $dayjob or exploring it for fun
13
- and think about what the minimum speed increase (or ram reduction or whatever) you want/need would be.
14
- What if it took a month for folk to help you achieve that? A year?
12
+ This page focuses on the simple notions of "speed" and "ram usage".
15
13
16
- = head1 Identifying the problem
14
+ = head1 First, clarify the problem(s)
15
+
16
+ B < Make sure you're not wasting time on the wrong code > : start by identifying your
17
+ L < "critical 3%"|https://en.wikiquote.org/wiki/Donald_Knuth > by "profiling" as explained below.
17
18
18
- = head2 C < now - INIT now >
19
+ = head2 Timing with C < now - INIT now >
19
20
20
21
Expressions of the form C < now - BEGIN now > , where C < BEGIN > is a
21
22
L < phase in the running of a Perl 6 program|/language/phasers > , provide a great idiom for timing code snippets.
@@ -29,19 +30,23 @@ you can write lines like:
29
30
The C < now > to the left of C < INIT > runs 0.0018558 seconds I < later > than the C < now > to the right of the C < INIT >
30
31
because the latter occurs during L < the INIT phase|/language/phasers#INIT > .
31
32
32
- = head2 C < prof-m: your code goes here >
33
+ = head2 Profiling with C < prof-m: your code goes here >
33
34
34
35
Entering C < prof-m: your code goes here > in the L < #perl6 channel|http://doc.perl6.org/language/glossary#IRC >
35
36
invokes an evalbot that runs a Perl 6 compiler with a C < --profile > option.
36
37
The evalbot's output includes a link to L < profile info|https://en.wikipedia.org/wiki/Profiling_(computer_programming) > :
37
38
39
+ = begin code :allow< L >
40
+
38
41
yournick prof-m: say 'hello world'
39
42
camelia prof-m 273e89: OUTPUT « hello world... »
40
43
.. Prof: L < http://p.p6c.org/20f9e25 >
41
44
45
+ = end code
46
+
42
47
Click on the profile info link to see a profile for C < say 'hello world' > .
43
48
44
- To learn how to interpret profile info, ask questions on channel.
49
+ To learn how to interpret the profile info, ask questions on channel.
45
50
46
51
= head2 Profiling locally
47
52
@@ -55,22 +60,36 @@ above) and ask questions on channel.
55
60
56
61
The Rakudo compiler's C < --profile-compile > option profiles the time and memory used to compile code.
57
62
58
- = head2 Benchmarks
63
+ = head2 Benchmarking
59
64
60
65
Use L < perl6-bench|https://github.com/japhb/perl6-bench > .
61
66
62
67
If you run perl6-bench for multiple compilers (typically versions of Perl 5, Perl 6, or NQP)
63
68
then results for each are visually overlaid on the same graphs to provide for quick and easy comparison.
64
69
65
- = head1 Improving code
70
+ = head2 Sharing a problem
71
+
72
+ Once you've used the above techniques to pinpoint code and performance that really matters you're in
73
+ a good place to share one problem at a time:
66
74
67
- This bears repeating: B < make sure you're not wasting time on the wrong code > . Start by identifying your
68
- L < "critical 3%"|https://en.wikiquote.org/wiki/Donald_Knuth > via profiling, as discussed in several sections above.
75
+ = item Distill a particular problem down to a one-liner or short public gist of code and pick one of the
76
+ timing/profiling options explained above to provide measurements of its performance.
77
+
78
+ = item Think about the minimum speed increase (or ram reduction or whatever) you need/want.
79
+ What if it took a month for folk to help you achieve that? A year?
80
+
81
+ = item Let folk know if your Perl 6 use-case is in a production setting or just for fun.
82
+
83
+ = head1 Solve the problem(s)
84
+
85
+ This bears repeating: B < make sure you're not wasting time on the wrong code > .
86
+ Start by identifying the L < "critical 3%"|https://en.wikiquote.org/wiki/Donald_Knuth > of your code.
69
87
70
88
= head2 Line by line
71
89
72
- A quick and fun way to try improve code line-by-line is to collaborate with others using the
73
- L < #perl6|http://doc.perl6.org/language/glossary#IRC > evalbot L < camelia|http://doc.perl6.org/language/glossary#camelia > .
90
+ A quick, fun and frequently very productive way to try improve code line-by-line is to collaborate with
91
+ others using the L < #perl6|http://doc.perl6.org/language/glossary#IRC > evalbot
92
+ L < camelia|http://doc.perl6.org/language/glossary#camelia > .
74
93
75
94
= head2 Routine by routine
76
95
@@ -89,28 +108,56 @@ previously existing set of definitions then you probably just made your code tha
89
108
= head2 Type-checks and call resolution
90
109
91
110
Most L < C < where > clauses|/type/Signature#Type_Constraints> -- and thus most
92
- L < subtypes|http://design.perl6.org/S12.html#Types_and_Subtypes > ) -- force dynamic (run-time)
111
+ L < subtypes|http://design.perl6.org/S12.html#Types_and_Subtypes > -- force dynamic (run-time)
93
112
type checking and call resolution. This is slower, or at least later, than compile-time.
94
113
95
114
Method calls are generally resolved as late as possible, so dynamically, at run-time,
96
- whereas sub calls are resolvable statically, at compile-time.
115
+ whereas sub calls are generally resolvable statically, at compile-time.
97
116
98
117
= head2 Choosing better algorithms
99
118
100
- Improving L < algorithmic efficiency|https://en.wikipedia.org/wiki/Algorithmic_efficiency > is
101
- one of the most reliable techniques for making large performance improvements regardless of language or compiler .
119
+ One of the most reliable techniques for making large performance improvements regardless of language or compiler
120
+ is to pick an algorithm better suited to your needs .
102
121
103
122
A classic example is L < Boyer-Moore|https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm > .
104
123
To match a small string in a large string, one obvious way to do it is to compare the first character of the
105
124
two strings and then, if they match, compare the second characters, or, if they don't match, compare the first
106
125
character of the small string with the second character in the large string, and so on. In contrast, the
107
- Boyer-Moore algorithm starts by comparing the *last* character of the small string with the corresponding
108
- character in the large string. For most strings the Boyer-Moore algorithm is close to N times faster where
109
- N is the length of the small string.
126
+ Boyer-Moore algorithm starts by comparing the *last* character of the small string with the correspondingly
127
+ positioned character in the large string. For most strings the Boyer-Moore algorithm is close to N times
128
+ faster algorithmically, where N is the length of the small string.
129
+
130
+ The next couple sections discuss two broad categories for improving algorithms that are made especially
131
+ easy to accomplish in Perl 6. For more on this topic, read the wikipedia page on
132
+ L < algorithmic efficiency|https://en.wikipedia.org/wiki/Algorithmic_efficiency > ,
133
+ especially the See also section near the end.
110
134
111
- = head2 Changing sequential/blocking code to parallel/non-blocking
135
+ = head3 Making list processing lazy
112
136
113
- This is a very important class of algorithmic improvement.
137
+ This a specific example of an algorithmic improvement. It's especially noteworthy when using languages
138
+ like Perl 6 that have built in support for lazy lists because the lazy equivalent of eager (non-lazy)
139
+ code is attractively simple.
140
+
141
+ A classic example is processing a large text file. An obvious simple approach is to slurp the lines
142
+ of the file into an array storing each line as an array element and then loop through that array:
143
+
144
+ my @lines = slurp 'largefile.txt';
145
+ for @lines -> $line {
146
+ # do something with $line
147
+ }
148
+
149
+ But if 'largefile.txt' contains a million very long lines you just used up a ton of memory
150
+ and it may well take quite a while before your code starts to do something with the first line.
151
+
152
+ A lazy alternative:
153
+
154
+ for 'largefile.txt'.IO.lines -> $line {
155
+ # do something with $line
156
+ }
157
+
158
+ = head3 Changing sequential/blocking code to parallel/non-blocking
159
+
160
+ This is another very important class of algorithmic improvement.
114
161
115
162
See the slides for
116
163
L < Parallelism, Concurrency, and Asynchrony in Perl 6|http://jnthn.net/papers/2015-yapcasia-concurrency.pdf#page=17 >
@@ -142,7 +189,7 @@ Perl 5's compiler can be treated as a C lib. Mix in Perl 6 types, the L<MOP|/lan
142
189
programming that someone else has done for you, and the upshot is that you can conveniently
143
190
L < use Perl 5 modules in Perl 6|http://stackoverflow.com/a/27206428/1077672 > .
144
191
145
- More generally, Perl 6 is designed to be able to smoothly interop with any other language and there are a number
192
+ More generally, Perl 6 is designed to be able to smoothly interop with other languages and there are a number
146
193
of L < modules aimed at providing convenient use of libs from other langs|http://modules.perl6.org/#q=inline > .
147
194
148
195
= head2 Speeding up Rakudo itself
@@ -161,20 +208,33 @@ If you can write Perl 6 you can fairly easily learn to use and improve the mid-l
161
208
at least from a pure language point of view.
162
209
Start with L < NQP and internals course|http://edumentab.github.io/rakudo-and-nqp-internals-course/ > .
163
210
164
- = item Finally, if low-level C hacking is your idea of fun, checkout L < MoarVM|http://moarvm.org > .
211
+ = item If low-level C hacking is your idea of fun, checkout L < MoarVM|http://moarvm.org > .
165
212
166
213
= head2 Still need more?
167
214
168
- There are many other things to consider:
169
- improving L < data alignment|https://en.wikipedia.org/wiki/Data_structure_alignment > ,
215
+ There are many other things to consider.
216
+
217
+ Some Perl 6 (or Rakudo) specific performance topics not yet covered in this page include
218
+ use of gather/take, use of junctions, and string handling.
219
+
220
+ General topics -- not specific to Perl 6 or Rakudo -- include improving
221
+ L < data alignment|https://en.wikipedia.org/wiki/Data_structure_alignment > ,
170
222
L < data granularity|https://en.wikipedia.org/wiki/Granularity#Data_granularity > ,
171
223
L < data compression|https://en.wikipedia.org/wiki/Data_compression > , and
172
- L < locality of reference|https://en.wikipedia.org/wiki/Locality_of_reference > to name a few.
224
+ L < locality of reference|https://en.wikipedia.org/wiki/Locality_of_reference > .
225
+
173
226
If you think some topic needs more coverage on this page please submit a PR or tell someone your idea.
174
227
Thanks. :)
175
228
176
- B < Tried everything? Frustrated? > Please consider talking to someone in the community about your use-case
177
- before giving up or concluding the answer to
178
- L < Is Perl 6 fast enough for me?|http://doc.perl6.org/language/faq#Is_Perl_6_fast_enough_for_me? > is "No".
229
+ = head1 Not getting the results you need/want?
230
+
231
+ If you've tried everything on this page to no avail, please consider discussing things with a
232
+ compiler dev on #perl6 so we can learn from your use-case and what you've found out about it so far.
233
+
234
+ Once you know one of the main devs knows of your plight, allow enough time for an informed response
235
+ (a few days or weeks depending on the exact nature of your problem and potential solutions).
236
+
237
+ If I < that > hasn't worked out either, please consider filing an issue discussing your experience at
238
+ L < User experience|https://github.com/perl6/user-experience/issues > before moving on. Thanks. :)
179
239
180
240
= end pod
0 commit comments