#!/usr/bin/perl -w use strict; use warnings; use lib '../lib'; use lib '../../Class-Std-Fast/lib'; use lib '/home/martin/workspace/SOAP-WSDL_XS/blib/lib'; use lib '/home/martin/workspace/SOAP-WSDL_XS/blib/arch'; use lib '../t/lib'; # use SOAP::WSDL::SAX::MessageHandler; use Benchmark qw(cmpthese timethese); use SOAP::WSDL::Expat::MessageParser; use SOAP::WSDL::Expat::Message2Hash; use SOAP::WSDL::Expat::MessageParser_XS; use SOAP::Lite; use XML::Simple; use XML::LibXML; use MyComplexType; use MyElement; use MySimpleType; my $xml = q{ Test2 Test3 Test4 Test5 Test6 Test7 Test8 Test9 Test10 Test11 Test12 Test13 Test55 Test14 Test15 Test16 Test17 Test18 Test19 Test20 Test21 Test22 Test23 Test24 Test25 Test565 Test27 Test28 Test29 Test30 Test31 Test32 Test33 Test34 Test35 Test36 Test37 Test38 Test55 }; my $parser = SOAP::WSDL::Expat::MessageParser->new({ class_resolver => 'FakeResolver' }); my $hash_parser = SOAP::WSDL::Expat::Message2Hash->new(); $XML::Simple::PREFERRED_PARSER = 'XML::Parser'; print "xml length: ${ \length $xml } bytes\n"; my $libxml = XML::LibXML->new(); $libxml->keep_blanks(0); my @data; my $deserializer = SOAP::Deserializer->new(); my $parser_xs = SOAP::WSDL::Expat::MessageParser_XS->new({ class_resolver => 'FakeResolver' }); sub libxml_test { my $dom = $libxml->parse_string( $xml ); push @data, dom2hash( $dom->firstChild ); }; sub dom2hash { for ($_[0]->childNodes) { if (exists $_[1]->{ $_->nodeName }) { if (ref $_[1]->{ $_->nodeName } eq 'ARRAY') { if ($_->nodeName eq '#text') { push @{ $_[1] } ,$_->textContent; } else { push @{ $_[1]->{ $_->nodeName } }, dom2hash( $_, {} ); } } else { if ($_->nodeName eq '#text') { $_[1] = [ $_[1], $_->textContent() ]; } else { $_[1]->{ $_->nodeName } = [ $_[1]->{ $_->nodeName } , dom2hash( $_, {} ) ]; } } } else { if ($_->nodeName eq '#text') { $_[1] = $_->textContent(); } else { $_[1]->{ $_->nodeName } = dom2hash( $_, {} ); } } } return $_[1]; } cmpthese 5000, { 'SOAP::WSDL (Hash)' => sub { push @data, $hash_parser->parse( $xml ) }, 'SOAP::WSDL (XSD)' => sub { push @data, $parser->parse( $xml ) }, 'SOAP::WSDL_XS (XSD)' => sub { push @data, $parser_xs->parse_string( $xml ) }, 'XML::Simple (Hash)' => sub { push @data, XMLin $xml }, 'XML::LibXML (DOM)' => sub { push @data, $libxml->parse_string( $xml ) }, 'XML::LibXML (Hash)' => \&libxml_test, 'SOAP::Lite' => sub { push @data, $deserializer->deserialize( $xml ) }, }; # data classes reside in t/lib/Typelib/ BEGIN { package FakeResolver; { my %class_list = ( 'MyAtomicComplexTypeElement' => 'MyAtomicComplexTypeElement', 'MyAtomicComplexTypeElement/test' => 'MyAtomicComplexTypeElement', 'MyAtomicComplexTypeElement/test/test2' => 'MyTestElement2', ); sub get_typemap { return \%class_list; }; sub get_map { return \%class_list }; sub new { return bless {}, 'FakeResolver' }; sub get_class { my $name = join('/', @{ $_[1] }); return ($class_list{ $name }) ? $class_list{ $name } : warn "no class found for $name"; }; }; }; __END__ Output on my machine: xml length: 641 bytes Rate SOAP::Lite XML::Simple (Hash) SOAP::WSDL (XSD) XML::LibXML (Hash) SOAP::WSDL (Hash) SOAP::WSDL_XS (XSD) XML::LibXML (DOM) SOAP::Lite 446/s -- -54% -72% -73% -80% -95% -96% XML::Simple (Hash) 963/s 116% -- -39% -41% -57% -89% -91% SOAP::WSDL (XSD) 1587/s 256% 65% -- -3% -29% -81% -86% XML::LibXML (Hash) 1629/s 265% 69% 3% -- -27% -81% -85% SOAP::WSDL (Hash) 2222/s 398% 131% 40% 36% -- -74% -80% SOAP::WSDL_XS (XSD) 8475/s 1798% 780% 434% 420% 281% -- -24% XML::LibXML (DOM) 11111/s 2389% 1053% 600% 582% 400% 31% --