File Coverage

blib/lib/Benchmark/Serialize/Library.pm
Criterion Covered Total %
statement 12 55 21.8
branch 0 18 0.0
condition 0 11 0.0
subroutine 4 11 36.3
pod 3 3 100.0
total 19 98 19.3


line stmt bran cond sub pod time code
1             package Benchmark::Serialize::Library;
2              
3 1     1   7 use strict;
  1         2  
  1         41  
4 1     1   7 use warnings;
  1         2  
  1         33  
5              
6 1     1   924 use UNIVERSAL::require qw();
  1         1588  
  1         20  
7 1     1   5 use Carp;
  1         2  
  1         2062  
8              
9             =head1 NAME
10              
11             Benchmark::Serialize::Library - Library of serialization modules
12              
13             =head1 VERSION
14              
15             Version 0.08
16              
17             =cut
18              
19             our $VERSION = '0.08';
20              
21             =head1 SYNOPSIS
22              
23             use Benchmark::Serialize::Library;
24              
25             Benchmark::Serialize::Library->register(
26             MyModule => {
27             deflate => sub { MyModule::deflate( $_[0] ) },
28             inflate => sub { MyModule::inflate( $_[0] ) },
29             }
30             );
31              
32             my %benchmarks = Benchmark::Serialize::Library->load( ":all" );
33              
34             =head1 DESCRIPTION
35              
36             This module contains a library of serialization routines for use with Benchmark::Serialize
37              
38             =cut
39              
40             my $benchmarks = {
41             'AnyMongo::BSON' => {
42             deflate => sub { AnyMongo::BSON::bson_encode( $_[0] ) },
43             inflate => sub { AnyMongo::BSON::bson_decode( $_[0] ) },
44             },
45             'Bencode' => {
46             deflate => sub { Bencode::bencode($_[0]) },
47             inflate => sub { Bencode::bdecode($_[0]) }
48             },
49             'Convert::Bencode' => {
50             deflate => sub { Convert::Bencode::bencode($_[0]) },
51             inflate => sub { Convert::Bencode::bdecode($_[0]) }
52             },
53             'Convert::Bencode_XS' => {
54             deflate => sub { Convert::Bencode_XS::bencode($_[0]) },
55             inflate => sub { Convert::Bencode_XS::bdecode($_[0]) }
56             },
57             'Data::asXML' => {
58             deflate => sub { Data::asXML->new(pretty=>0)->encode($_[0])->toString },
59             inflate => sub { Data::asXML->new(pretty=>0)->decode($_[0]) },
60             xml => 1,
61             },
62             'Data::Dumper' => {
63             deflate => sub { Data::Dumper->Dump([ $_[0] ]) },
64             inflate => sub { my $VAR1; eval $_[0] },
65             default => 1,
66             core => 1,
67             },
68             'Data::MessagePack' => {
69             deflate => sub { Data::MessagePack->pack($_[0]) },
70             inflate => sub { Data::MessagePack->unpack($_[0]) },
71             },
72             'Data::Taxi' => {
73             deflate => sub { Data::Taxi::freeze($_[0]) },
74             inflate => sub { Data::Taxi::thaw($_[0]) },
75             xml => 1,
76             },
77             'Data::Pond' => {
78             deflate => sub { Data::Pond::pond_write_datum($_[0]) },
79             inflate => sub { Data::Pond::pond_read_datum($_[0]) },
80             },
81             'Data::Pond,eval' => {
82             deflate => sub { Data::Pond::pond_write_datum($_[0]) },
83             inflate => sub { eval($_[0]) },
84             packages => ['Data::Pond'],
85             },
86             'FreezeThaw' => {
87             deflate => sub { FreezeThaw::freeze($_[0]) },
88             inflate => sub { FreezeThaw::thaw($_[0]) },
89             default => 1
90             },
91             'JSON::PP' => {
92             deflate => sub { JSON::PP::encode_json($_[0]) },
93             inflate => sub { JSON::PP::decode_json($_[0]) },
94             default => 1,
95             json => 1
96             },
97             'JSON::XS' => {
98             deflate => sub { JSON::XS::encode_json($_[0]) },
99             inflate => sub { JSON::XS::decode_json($_[0]) },
100             default => 1,
101             json => 1
102             },
103             'JSON::XS,pretty' => {
104             deflate => sub { $_[1]->encode( $_[0] ) },
105             inflate => sub { $_[1]->decode( $_[0] ) },
106             args => sub { JSON::XS->new->pretty(1)->allow_blessed(1)->convert_blessed(1)->canonical(1) },
107             json => 1,
108             packages => ['JSON::XS'],
109             },
110             'JSON::DWIW' => {
111             deflate => sub { JSON::DWIW->to_json($_[0]) },
112             inflate => sub { JSON::DWIW::deserialize($_[0]) },
113             json => 1,
114             },
115             'JSYNC' => {
116             deflate => sub { JSYNC::dump($_[0]) },
117             inflate => sub { JSYNC::load($_[0]) },
118             },
119             'Storable' => {
120             deflate => sub { Storable::nfreeze($_[0]) },
121             inflate => sub { Storable::thaw($_[0]) },
122             default => 1,
123             core => 1,
124             },
125             'PHP::Serialization' => {
126             deflate => sub { PHP::Serialization::serialize($_[0]) },
127             inflate => sub { PHP::Serialization::unserialize($_[0]) }
128             },
129             'PHP::Serialization::XS' => {
130             deflate => sub { PHP::Serialization::XS::serialize($_[0]) },
131             inflate => sub { PHP::Serialization::XS::unserialize($_[0]) }
132             },
133             'RPC::XML' => {
134             deflate => sub { RPC::XML::response->new($_[0])->as_string },
135             inflate => sub { RPC::XML::ParserFactory->new->parse($_[0])->value },
136             packages => ['RPC::XML', 'RPC::XML::ParserFactory'],
137             xml => 1,
138             },
139             'YAML::Old' => {
140             deflate => sub { YAML::Old::Dump($_[0]) },
141             inflate => sub { YAML::Old::Load($_[0]) },
142             default => 1,
143             yaml => 1
144             },
145             'YAML::XS' => {
146             deflate => sub { YAML::XS::Dump($_[0]) },
147             inflate => sub { YAML::XS::Load($_[0]) },
148             default => 1,
149             yaml => 1
150             },
151             'YAML::Tiny' => {
152             deflate => sub { YAML::Tiny::Dump($_[0]) },
153             inflate => sub { YAML::Tiny::Load($_[0]) },
154             default => 1,
155             yaml => 1
156             },
157             'XML::Simple' => {
158             deflate => sub { XML::Simple::XMLout($_[0]) },
159             inflate => sub { XML::Simple::XMLin($_[0]) },
160             default => 1,
161             xml => 1,
162             },
163             'XML::TreePP' => {
164             deflate => sub { XML::TreePP->new()->write( $_[0] ) },
165             inflate => sub { XML::TreePP->new()->parse( $_[0] ) },
166             xml => 1,
167             },
168             };
169              
170             =head2 Library methods
171              
172             This class provides the following methods
173              
174             =over 5
175              
176             =item register( NAME => SPECIFICATION )
177              
178             Registers a new benchmarkable form of serialization. A specification is a
179             hashref containing the following fields:
180              
181             =over 5
182              
183             =item deflate (required)
184              
185             A coderef taking one argument (a perl structure) and returns the serialized
186             structure
187              
188             =item inflate (required)
189              
190             A coderef taking one argument (a serialized structure) and returns the
191             perl structure
192              
193             =item packages (optional)
194              
195             A array reference containing modules to be loaded. The default value is the
196             name of the benchmark.
197              
198             =item args (optional)
199              
200             A coderef returning a list of aditional arguments for the deflate and inflate
201             routines. Only run once during initialization of benchmark.
202              
203             =back
204              
205             All additional fields are interpreted as tags used for selecting benchmarks.
206              
207             =cut
208              
209             sub register {
210 0     0 1   my $class = shift;
211 0           my $name = shift;
212 0           my $benchmark = shift;
213              
214 0 0 0       croak "Missing deflate and/or inflate field"
215             unless exists $benchmark->{deflate} && $benchmark->{inflate};
216              
217 0 0         croak "Existing benchmark"
218             if exists $benchmarks->{$name};
219              
220 0           $benchmarks->{$name} = $benchmark;
221 0           return 1;
222             }
223              
224             =item load NAME|TAG|BENCHMARK ...
225              
226             Loads and initializes a number of benchmarks. Arguments can be either
227             registered names, registered tags, or unregistered benchmarks following the
228             same format as the C method.
229              
230             Returns a list of benchmarks
231              
232             =cut
233              
234             sub load {
235 0     0 1   my $class = shift;
236              
237 0           my %benchmark;
238 0           for my $spec (@_) {
239 0 0 0       if ( ref $spec eq "HASH" ) {
    0          
    0          
    0          
    0          
240 0           $benchmark{ $spec->{name} } = $spec;
241              
242             } elsif ( $spec eq "all" or $spec eq ":all" ) {
243 0           $benchmark { $_ } = $benchmarks->{ $_ } for keys %{ $benchmarks };
  0            
244            
245             } elsif ( $spec eq "default" ) {
246 0           $benchmark{ $_ } = $benchmarks->{ $_ } for grep { $benchmarks->{ $_ }->{default} } keys %{ $benchmarks };
  0            
  0            
247            
248             } elsif ( $spec =~ /^:(.*)/ ) {
249 0           $benchmark{ $_ } = $benchmarks->{ $_ } for grep { $benchmarks->{ $_ }->{$1} } keys %{ $benchmarks };
  0            
  0            
250            
251             } elsif ( exists $benchmarks->{ $spec } ) {
252 0           $benchmark{ $spec } = $benchmarks->{ $spec }
253            
254             } else {
255 0           warn "Unknown benchmark '$spec'.";
256             }
257             }
258              
259 0           my @list;
260             BENCHMARK:
261 0           foreach my $name ( keys %benchmark ) {
262              
263 0           my $benchmark = $benchmark{$name};
264 0 0         my @packages = ( exists($benchmark->{packages}) ? @{ $benchmark->{packages} } : $name );
  0            
265            
266 0   0       $_->require or next BENCHMARK for @packages;
267              
268 0 0 0       $benchmark->{args} = [ $benchmark->{args}->() ] if exists $benchmark->{args}
269             && ref $benchmark->{args} eq "CODE";
270              
271 0           $benchmark->{name} = $name;
272 0           $benchmark->{version} = $packages[0]->VERSION;
273              
274 0           push @list, bless $benchmark, "Benchmark::Serialize::Benchmark";
275             }
276              
277 0           return @list;
278             }
279              
280             =item list
281              
282             Returns a list of all available benchmarks. For each benchmark both the name
283             and the version is returned in a array ref.
284              
285             =cut
286              
287             sub list {
288 0     0 1   return map { [ $_->name, $_->version ] } Benchmark::Serialize::Library->load(":all");
  0            
289             }
290              
291             =back
292              
293             =cut
294              
295             package Benchmark::Serialize::Benchmark;
296              
297             =head2 Benchmark methods
298              
299             Each benchmark is represented by a object with the following mathods
300              
301             =over 5
302              
303             =item deflate
304              
305             Takes a perl structure as argument and returns the serialized form
306              
307             =cut
308              
309             sub deflate {
310 0     0     $_[0]->{deflate}->($_[1], @{ $_[0]->{args} } );
  0            
311             }
312              
313             =item inflate
314              
315             Takes a serialized form as argument and returns the perl structure.
316              
317             =cut
318              
319             sub inflate {
320 0     0     $_[0]->{inflate}->($_[1], @{ $_[0]->{args} } );
  0            
321             }
322              
323             =item name
324              
325             Returns the name of the benchmark
326              
327             =cut
328              
329             sub name {
330 0     0     my $self = shift;
331              
332 0           return $self->{name};
333             }
334              
335             =item version
336              
337             Returns the module version of the benchmark. For benchmark needing multiple
338             loaded modules, the first in the specification list is used.
339              
340             =cut
341              
342             sub version {
343 0     0     my $self = shift;
344              
345 0           return $self->{version};
346             }
347              
348             =back
349              
350             =head2 Known tags
351              
352             The following tags are usec in the standard library
353              
354             =over 5
355              
356             =item :all - All modules with premade benchmarks
357              
358             =item :default - A default set of serialization modules
359              
360             =item :core - Serialization modules included in core
361              
362             =item :json - JSON modules
363              
364             =item :yaml - YAML modules
365              
366             =item :xml - XML formats
367              
368             =back
369              
370              
371             =head1 AUTHOR
372              
373             Peter Makholm, C<< >>
374              
375             =head1 BUGS
376              
377             Please report any bugs or feature requests to C
378             rt.cpan.org>, or through
379             the web interface at
380             L. I will
381             be notified, and then you'll
382             automatically be notified of progress on your bug as I make changes.
383              
384             =head1 ACKNOWLEDGEMENTS
385              
386             This module started out as a script written by Christian Hansen, see
387             http://idisk.mac.com/christian.hansen/Public/perl/serialize.pl
388              
389             =head1 COPYRIGHT & LICENSE
390              
391             Copyright 2009-2010 Peter Makholm.
392              
393             This program is free software; you can redistribute it and/or modify it
394             under the terms of either: the GNU General Public License as published
395             by the Free Software Foundation; or the Artistic License.
396              
397             See http://dev.perl.org/licenses/ for more information.
398              
399              
400             =cut
401              
402             1;