initial commit
[urisagit/Perl-Docs.git] / extras / slurp_bench.pl
CommitLineData
635c7876 1#!/usr/local/bin/perl
2
3use strict ;
4use warnings ;
5
6use Getopt::Long ;
7use Benchmark qw( timethese cmpthese ) ;
8use Carp ;
9use FileHandle ;
10use Fcntl qw( :DEFAULT :seek );
11
12use File::Slurp () ;
13
14my $file = 'slurp_data' ;
15
16GetOptions (\my %opts,
17 qw( slurp spew scalar list sizes=s key duration=i help ) ) ;
18
19parse_options() ;
20
21run_benchmarks() ;
22
23unlink $file ;
24
25exit ;
26
27my( @lines, $text, $size ) ;
28
29sub run_benchmarks {
30
31 foreach my $size ( @{$opts{sizes}} ) {
32
33 @lines = ( 'a' x 80 . "\n") x $size ;
34 $text = join( '', @lines ) ;
35 $size = length $text ;
36
37 File::Slurp::write_file( $file, $text ) ;
38
39# bench_list_slurp( $size ) if $opts{list} && $opts{slurp} ;
40# bench_scalar_slurp( $size ) if $opts{scalar} && $opts{slurp} ;
41 bench_spew_list()
42# bench_scalar_spew( $size ) if $opts{scalar} && $opts{spew} ;
43 }
44}
45
46sub bench_spew_list {
47
48 return unless $opts{list} && $opts{spew} ;
49
50 print "\n\nWriting (Spew) a list of lines: Size = $size bytes\n\n" ;
51
52 my $result = timethese( $opts{duration}, {
53
54 'FS::write_file' =>
55 sub { File::Slurp::write_file( $file, @lines ) },
56
57 'print' =>
58 sub { print_file( $file, @lines ) },
59
60 'print/join' =>
61 sub { print_join_file( $file, @lines ) },
62
63 'syswrite/join' =>
64 sub { syswrite_join_file( $file, @lines ) },
65
66 'original write_file' =>
67 sub { orig_write_file( $file, @lines ) },
68
69 } ) ;
70
71 cmpthese( $result ) ;
72}
73
74# sub bench_scalar_spew {
75
76# my ( $size ) = @_ ;
77
78# print "\n\nScalar Spew of $size file\n\n" ;
79
80# my $result = timethese( $dur, {
81
82# new =>
83# sub { File::Slurp::write_file( $file, $text ) },
84
85# new_ref =>
86# sub { File::Slurp::write_file( $file, \$text ) },
87
88# print_file =>
89# sub { print_file( $file, $text ) },
90
91# print_join_file =>
92# sub { print_join_file( $file, $text ) },
93
94# syswrite_file =>
95# sub { syswrite_file( $file, $text ) },
96
97# syswrite_file2 =>
98# sub { syswrite_file2( $file, $text ) },
99
100# orig_write_file =>
101# sub { orig_write_file( $file, $text ) },
102
103# } ) ;
104
105# cmpthese( $result ) ;
106# }
107
108# sub bench_scalar_slurp {
109
110# my ( $size ) = @_ ;
111
112# print "\n\nScalar Slurp of $size file\n\n" ;
113
114# my $buffer ;
115
116# my $result = timethese( $dur, {
117
118# new =>
119# sub { my $text = File::Slurp::read_file( $file ) },
120
121# new_buf_ref =>
122# sub { my $text ;
123# File::Slurp::read_file( $file, buf_ref => \$text ) },
124# new_buf_ref2 =>
125# sub {
126# File::Slurp::read_file( $file, buf_ref => \$buffer ) },
127# new_scalar_ref =>
128# sub { my $text =
129# File::Slurp::read_file( $file, scalar_ref => 1 ) },
130
131# read_file =>
132# sub { my $text = read_file( $file ) },
133
134# sysread_file =>
135# sub { my $text = sysread_file( $file ) },
136
137# orig_read_file =>
138# sub { my $text = orig_read_file( $file ) },
139
140# 'Slurp.pm scalar' =>
141# sub { my $text = slurp_scalar( $file ) },
142
143# file_contents =>
144# sub { my $text = file_contents( $file ) },
145
146# file_contents_no_OO =>
147# sub { my $text = file_contents_no_OO( $file ) },
148# } ) ;
149
150# cmpthese( $result ) ;
151# }
152
153# sub bench_list_slurp {
154
155# my ( $size ) = @_ ;
156
157# print "\n\nList Slurp of $size file\n\n" ;
158
159# my $result = timethese( $dur, {
160
161# new =>
162# sub { my @lines = File::Slurp::read_file( $file ) },
163
164# new_array_ref =>
165# sub { my $lines_ref =
166# File::Slurp::read_file( $file, array_ref => 1 ) },
167
168# new_in_anon_array =>
169# sub { my $lines_ref =
170# [ File::Slurp::read_file( $file ) ] },
171
172# read_file =>
173# sub { my @lines = read_file( $file ) },
174
175# sysread_file =>
176# sub { my @lines = sysread_file( $file ) },
177
178# orig_read_file =>
179# sub { my @lines = orig_read_file( $file ) },
180
181# 'Slurp.pm to array' =>
182# sub { my @lines = slurp_array( $file ) },
183
184# orig_slurp_to_array_ref =>
185# sub { my $lines_ref = orig_slurp_to_array( $file ) },
186# } ) ;
187
188# cmpthese( $result ) ;
189# }
190
191
192###########################
193# write file benchmark subs
194###########################
195
196
197sub print_file {
198
199 my( $file_name ) = shift ;
200
201 local( *FH ) ;
202
203 open( FH, ">$file_name" ) || carp "can't create $file_name $!" ;
204
205 print FH @_ ;
206}
207
208sub print_file2 {
209
210 my( $file_name ) = shift ;
211
212 local( *FH ) ;
213
214 my $mode = ( -e $file_name ) ? '<' : '>' ;
215
216 open( FH, "+$mode$file_name" ) || carp "can't create $file_name $!" ;
217
218 print FH @_ ;
219}
220
221sub print_join_file {
222
223 my( $file_name ) = shift ;
224
225 local( *FH ) ;
226
227 my $mode = ( -e $file_name ) ? '<' : '>' ;
228
229 open( FH, "+$mode$file_name" ) || carp "can't create $file_name $!" ;
230
231 print FH join( '', @_ ) ;
232}
233
234
235sub syswrite_join_file {
236
237 my( $file_name ) = shift ;
238
239 local( *FH ) ;
240
241 open( FH, ">$file_name" ) || carp "can't create $file_name $!" ;
242
243 syswrite( FH, join( '', @_ ) ) ;
244}
245
246sub sysopen_syswrite_join_file {
247
248 my( $file_name ) = shift ;
249
250 local( *FH ) ;
251
252 sysopen( FH, $file_name, O_WRONLY | O_CREAT ) ||
253 carp "can't create $file_name $!" ;
254
255 syswrite( FH, join( '', @_ ) ) ;
256}
257
258sub orig_write_file
259{
260 my ($f, @data) = @_;
261
262 local(*F);
263
264 open(F, ">$f") || croak "open >$f: $!";
265 (print F @data) || croak "write $f: $!";
266 close(F) || croak "close $f: $!";
267 return 1;
268}
269
270
271#######################
272# top level subs for script
273
274#######################
275
276sub parse_options {
277
278 help() if $opts{help} ;
279
280 key() if $opts{key} ;
281
282 unless( $opts{spew} || $opts{slurp} ) {
283
284 $opts{spew} = 1 ;
285 $opts{slurp} = 1 ;
286 }
287
288 unless( $opts{list} || $opts{scalar} ) {
289
290 $opts{list} = 1 ;
291 $opts{scalar} = 1 ;
292 }
293
294 $opts{sizes} = [split ',', ( $opts{sizes} || '10,100,1000' ) ];
295
296 $opts{duration} ||= -2 ;
297}
298
299sub key {
300
301 print <<'KEY' ;
302
303Key to Slurp/Spew Benchmarks
304
305
306Write a list of lines to a file
307
308 Key Description/Source
309 --- ------------------
310
311 FS:write_file Current File::Slurp::write_file
312 FS:write_file_ref Current File::Slurp::write_file (scalar ref)
313 print Open a file and call print()
314 syswrite/join Open a file, call syswrite on joined lines
315 sysopen/syswrite Sysopen a file, call syswrite on joined lines
316 original write_file Original (pre 9999.*) File::Slurp::write_file
317
318
319KEY
320
321 exit ;
322}
323
324sub help {
325
326 die <<DIE ;
327
328Usage: $0 [--list] [--scalar] [--slurp] [--spew]
329 [--sizes=10,100] [--help]
330
331 --list Run the list context benchmarks
332 --scalar Run the scalar context benchmarks
333 Those default to on unless one is set
334
335 --slurp Run the slurp benchmarks
336 --spew Run the spew benchmarks
337 Those default to on unless one is set
338
339 --sizes Comma separated list of file sizes to benchmark
340 Defaults to 10,100,1000
341
342 --key Print the benchmark names and code orig_ins
343
344 --help Print this help text
345
346DIE
347
348}
349
350
351__END__
352
353
354sub bench_scalar_spew {
355
356 my ( $size ) = @_ ;
357
358 print "\n\nScalar Spew of $size file\n\n" ;
359
360 my $result = timethese( $dur, {
361
362 new =>
363 sub { File::Slurp::write_file( $file, $text ) },
364
365 new_ref =>
366 sub { File::Slurp::write_file( $file, \$text ) },
367
368 print_file =>
369 sub { print_file( $file, $text ) },
370
371 print_join_file =>
372 sub { print_join_file( $file, $text ) },
373
374 syswrite_file =>
375 sub { syswrite_file( $file, $text ) },
376
377 syswrite_file2 =>
378 sub { syswrite_file2( $file, $text ) },
379
380 orig_write_file =>
381 sub { orig_write_file( $file, $text ) },
382
383 } ) ;
384
385 cmpthese( $result ) ;
386}
387
388sub bench_scalar_slurp {
389
390 my ( $size ) = @_ ;
391
392 print "\n\nScalar Slurp of $size file\n\n" ;
393
394 my $buffer ;
395
396 my $result = timethese( $dur, {
397
398 new =>
399 sub { my $text = File::Slurp::read_file( $file ) },
400
401 new_buf_ref =>
402 sub { my $text ;
403 File::Slurp::read_file( $file, buf_ref => \$text ) },
404 new_buf_ref2 =>
405 sub {
406 File::Slurp::read_file( $file, buf_ref => \$buffer ) },
407 new_scalar_ref =>
408 sub { my $text =
409 File::Slurp::read_file( $file, scalar_ref => 1 ) },
410
411 read_file =>
412 sub { my $text = read_file( $file ) },
413
414 sysread_file =>
415 sub { my $text = sysread_file( $file ) },
416
417 orig_read_file =>
418 sub { my $text = orig_read_file( $file ) },
419
420 orig_slurp =>
421 sub { my $text = orig_slurp_to_scalar( $file ) },
422
423 file_contents =>
424 sub { my $text = file_contents( $file ) },
425
426 file_contents_no_OO =>
427 sub { my $text = file_contents_no_OO( $file ) },
428 } ) ;
429
430 cmpthese( $result ) ;
431}
432
433sub bench_list_slurp {
434
435 my ( $size ) = @_ ;
436
437 print "\n\nList Slurp of $size file\n\n" ;
438
439 my $result = timethese( $dur, {
440
441 new =>
442 sub { my @lines = File::Slurp::read_file( $file ) },
443
444 new_array_ref =>
445 sub { my $lines_ref =
446 File::Slurp::read_file( $file, array_ref => 1 ) },
447
448 new_in_anon_array =>
449 sub { my $lines_ref =
450 [ File::Slurp::read_file( $file ) ] },
451
452 read_file =>
453 sub { my @lines = read_file( $file ) },
454
455 sysread_file =>
456 sub { my @lines = sysread_file( $file ) },
457
458 orig_read_file =>
459 sub { my @lines = orig_read_file( $file ) },
460
461 orig_slurp_to_array =>
462 sub { my @lines = orig_slurp_to_array( $file ) },
463
464 orig_slurp_to_array_ref =>
465 sub { my $lines_ref = orig_slurp_to_array( $file ) },
466 } ) ;
467
468 cmpthese( $result ) ;
469}
470
471######################################
472# uri's old fast slurp
473
474sub read_file {
475
476 my( $file_name ) = shift ;
477
478 local( *FH ) ;
479 open( FH, $file_name ) || carp "can't open $file_name $!" ;
480
481 return <FH> if wantarray ;
482
483 my $buf ;
484
485 read( FH, $buf, -s FH ) ;
486 return $buf ;
487}
488
489sub sysread_file {
490
491 my( $file_name ) = shift ;
492
493 local( *FH ) ;
494 open( FH, $file_name ) || carp "can't open $file_name $!" ;
495
496 return <FH> if wantarray ;
497
498 my $buf ;
499
500 sysread( FH, $buf, -s FH ) ;
501 return $buf ;
502}
503
504######################################
505# from File::Slurp.pm on cpan
506
507sub orig_read_file
508{
509 my ($file) = @_;
510
511 local($/) = wantarray ? $/ : undef;
512 local(*F);
513 my $r;
514 my (@r);
515
516 open(F, "<$file") || croak "open $file: $!";
517 @r = <F>;
518 close(F) || croak "close $file: $!";
519
520 return $r[0] unless wantarray;
521 return @r;
522}
523
524
525######################################
526# from Slurp.pm on cpan
527
528sub slurp {
529 local( $/, @ARGV ) = ( wantarray ? $/ : undef, @_ );
530 return <ARGV>;
531}
532
533sub slurp_array {
534 my @array = slurp( @_ );
535 return wantarray ? @array : \@array;
536}
537
538sub slurp_scalar {
539 my $scalar = slurp( @_ );
540 return $scalar;
541}
542
543######################################
544# very slow slurp code used by a client
545
546sub file_contents {
547 my $file = shift;
548 my $fh = new FileHandle $file or
549 warn("Util::file_contents:Can't open file $file"), return '';
550 return join '', <$fh>;
551}
552
553# same code but doesn't use FileHandle.pm
554
555sub file_contents_no_OO {
556 my $file = shift;
557
558 local( *FH ) ;
559 open( FH, $file ) || carp "can't open $file $!" ;
560
561 return join '', <FH>;
562}
563
564##########################