Re: [ANNOUNCE] Apache::SOAP 0.47 (mod_soap)
Paul, I've done some work on Keith Brown's SOAP module, and I like its design, but one thing I noticed is that it is slow. Even under mod_perl, it can take up to 1 second(!) to serialize a large data structure. I believe the reason is that it makes method calls for every element in the Perl data structure, and method calls in Perl are inefficient due to the symbol table lookups and @ISA checking. So the larger the data structure the worse the performance. (I added array support to it and tested an array of 200 values, which took ~1 sec to serialize under mod_perl). I'd be interested in speed comparisons between SOAP and SOAP::Lite. I've looked at your code, but not actually run it. It doesn't look like you use recursive method calls the way Keith does. Have you done any benchmarks on large data structure serialization? I assume deserialization performance will be roughly equivalent for SOAP vs. SOAP::Lite since they both use XML::Parser. I read the PERFORMANCE section on base64 encoding, but it didn't mention serialization speed. I am currently using SOAP, because I like the DM design, but I would switch to SOAP::Lite if its serialization speed is significantly better. Cheers, -Adi Paul Kulchenko wrote: you are dedicated to supporting the full SOAP API (not sure what SOAP::Lite leaves out). First thing I did seven months ago was my email to Keith Brown (author of DM's SOAP/Perl module) about possible ways for cooperation and I'v been told that he's willing to, but design of his module should be consistent with other DM's implementations and he has no plans to change it. There was no easy way to combine our efforts and I came up with another implementation. Don't want to praise myself, but feature set seems to be pretty comparable with other toolkits. I took ::Lite, just because SOAP namespace was already taken. It does much more than you can expect from something with suffix Lite. "Lite suffix reflects number of calories you should spend using this module".
Re: [ANNOUNCE] Apache::SOAP 0.47 (mod_soap)
Hi, Adi! performance. (I added array support to it and tested an array of 200 values, which took ~1 sec to serialize under mod_perl). I see I wasn't the only person who starts with adding Array support to it and I even made my copy of it SOAP1.1 compliant, but then Keith came with his compliant version. As for performance, I tried and got similar results on my machine. I don't know your environment, so I included all my scripts, so you may try them on your machine and let us know. Anyway, here is my results (win98): Benchmark: timing 10 iterations of 100x100, 1x100... 100x100: 10 wallclock secs ( 9.72 usr + 0.00 sys = 9.72 CPU) @ 1.03/s (n=10) 1x100: 9 wallclock secs ( 9.17 usr + 0.00 sys = 9.17 CPU) @ 1.09/s (n=10) So, time is about 1 sec for roundtrip to mod_perl (serialization - deserialization - invocation - serialization - deserialization) Time for serialization only is different: Benchmark: timing 100 iterations of (1)x200, (1x100)x200... (1)x200: 23 wallclock secs (23.34 usr + 0.00 sys = 23.34 CPU) @ 4.28/s (n=100) (1x100)x200: 25 wallclock secs (24.99 usr + 0.00 sys = 24.99 CPU) @ 4.00/s (n=100) So, about 4 times bette. Same script on Linux (serialization only): Benchmark: timing 100 iterations of (1)x200, (1x100)x200... (1)x200: 5 wallclock secs ( 5.53 usr + 0.01 sys = 5.54 CPU) (1x100)x200: 6 wallclock secs ( 5.79 usr + 0.02 sys = 5.81 CPU) About 18 times a second. Try these scripts in your environment for better results. # Serialization use SOAP::Lite; use Benchmark; $s = SOAP::Serializer-new; $array1 = [(1) x 200]; $array100 = [(1x100) x 200]; Benchmark::timethese(100, { '(1)x200' = sub { $s-method(a = $array1) }, '(1x100)x200' = sub { $s-method(a = $array100) }, }) # mod_perl use SOAP::Lite; $s = SOAP::Lite - uri('http://www.soaplite.com/My/Parameters') - proxy('http://localhost/soap') ; use Benchmark; $s-echo; # ignore first call, don't give a start to the first one $array1 = [(1) x 200]; $array100 = [(1 x 100) x 200]; Benchmark::timethese(10, { '1x100' = sub { $s-echo($array1) }, '100x100' = sub { $s-echo($array100) }, }) # second(!) to serialize a large data structure. I believe the reason is that it makes method calls for every element in the Perl data structure, and method calls in Perl are inefficient due to the symbol table lookups and @ISA checking. So the larger the data structure the worse the That's right, but first Perl caches calls that involve inheritance and second, I use the same scheme, because arrays can have everything inside and I need to call serialization function for every element in array. I did profiling for several versions and did some improvements, but there is no obvious stopper. I am currently using SOAP, because I like the DM design, but I would switch to SOAP::Lite if its serialization speed is significantly better. I'd like to know your results, with your Array implementation. Thank you. Best wishes, Paul. --- Adi Fairbank [EMAIL PROTECTED] wrote: Paul, I've done some work on Keith Brown's SOAP module, and I like its design, but one thing I noticed is that it is slow. Even under mod_perl, it can take up to 1 second(!) to serialize a large data structure. I believe the reason is that it makes method calls for every element in the Perl data structure, and method calls in Perl are inefficient due to the symbol table lookups and @ISA checking. So the larger the data structure the worse the performance. (I added array support to it and tested an array of 200 values, which took ~1 sec to serialize under mod_perl). I'd be interested in speed comparisons between SOAP and SOAP::Lite. I've looked at your code, but not actually run it. It doesn't look like you use recursive method calls the way Keith does. Have you done any benchmarks on large data structure serialization? I assume deserialization performance will be roughly equivalent for SOAP vs. SOAP::Lite since they both use XML::Parser. I read the PERFORMANCE section on base64 encoding, but it didn't mention serialization speed. I am currently using SOAP, because I like the DM design, but I would switch to SOAP::Lite if its serialization speed is significantly better. Cheers, -Adi Paul Kulchenko wrote: you are dedicated to supporting the full SOAP API (not sure what SOAP::Lite leaves out). First thing I did seven months ago was my email to Keith Brown (author of DM's SOAP/Perl module) about possible ways for cooperation and I'v been told that he's willing to, but design of his module should be consistent with other DM's implementations and he has no plans to change it. There was no easy way to combine our efforts and I came up with another implementation. Don't want to praise myself, but feature set seems
Re: [ANNOUNCE] Apache::SOAP 0.47 (mod_soap)
At 05:14 PM 2/24/2001 -0800, Paul Kulchenko wrote: That's right, but first Perl caches calls that involve inheritance and second, I use the same scheme, because arrays can have everything inside and I need to call serialization function for every element in array. I did profiling for several versions and did some improvements, but there is no obvious stopper. Is there any way to add an interface to basically provide serialization and deserialization hints? My experience in the way we use SOAP is that there are only a few core objects that really require SOAP and the rest can be on the front-end. Maybe using a CORBA-like IDL config? Thus, I could give a strong hint to SOAP::Lite that a particular array only contained one type of object... In the stuff I've been doing over the last year, I've always wrote my own serializer/deserializer from scratch because I wanted it to be fast and have control over optimization rather than using the libraries that already exist out there. Later, Gunther
Re: [ANNOUNCE] Apache::SOAP 0.47 (mod_soap)
Hi, Gunther! Is there any way to add an interface to basically provide serialization and deserialization hints? My experience in the way we use SOAP is that There is no way to ptovide hints, but you have several options to alter serializer/deserializer and use all other infrastructure. For example, you may override serializer completely from scratch and then register it with: my $soap = SOAP::Lite-serializer(My::Serializer-new)-... Or you may inherit your own serializer and specify it in the same way. The same thing is true about deserializer and about server side (these methods are available there also). I did some tests with overriding serializers and truly results are surprised me at least a little bit. Script is below. Results: o - (1)x200: 23 wallclock secs (23.68 usr + 0.00 sys = 23.68 CPU) @ 4.22/s (n=100) o - (1x100)x200: 25 wallclock secs (24.99 usr + 0.00 sys = 24.99 CPU) @ 4.00/s (n=100) a - (1)x200: 15 wallclock secs (15.33 usr + 0.00 sys = 15.33 CPU) @ 6.52/s (n=100) a - (1x100)x200: 16 wallclock secs (16.14 usr + 0.00 sys = 16.14 CPU) @ 6.20/s (n=100) t - (1)x200: 6 wallclock secs ( 5.11 usr + 0.00 sys = 5.11 CPU) @ 19.57/s (n=100) t - (1x100)x200: 6 wallclock secs ( 6.15 usr + 0.00 sys = 6.15 CPU) @ 16.26/s (n=100) x - (1)x200: 2 wallclock secs ( 2.08 usr + 0.00 sys = 2.08 CPU) @ 48.08/s (n=100) x - (1x100)x200: 3 wallclock secs ( 3.19 usr + 0.00 sys = 3.19 CPU) @ 31.35/s (n=100) First is default serializer. Second makes serialization only for first element of array and then duplicates the results, emulating procedure for one type for all elements. 50% better Third generates ready to use xml and provides it as the result (you may provide xml fragments during serialization) using serializer's tag function. Almost 5 times better comparing to default. Forth generates xml with by-hand coding. Almost 10 times better than default. Everithing else is generated by serializer, so you can insert your fragment seamlessly. It's definitely something to think about. I'll take a closer look, but it shows that having some information about data structure you may significantly speed up this process. You may alter serialization depending on user-defined class, depending on Object class, depending on ref type (array, hash, scalar), etc., so you have almost full control on serializer behavior. Create you own, override what you need, register it and you're done. Here is the script # -- -- -- -- -- -- -- -- -- -- -- use SOAP::Lite; use Benchmark; $s = SOAP::Serializer-new; $a = My::Serializer::Array-new; $x = My::Serializer::XML-new; $t = My::Serializer::XMLtag-new; $array1 = [(1) x 200]; $array100 = [(1x100) x 200]; Benchmark::timethese(100, { 'o - (1)x200' = sub { $s-method(a = $array1) }, 'o - (1x100)x200' = sub { $s-method(a = $array100) }, 'a - (1)x200' = sub { $a-method(a = $array1) }, 'a - (1x100)x200' = sub { $a-method(a = $array100) }, 'x - (1)x200' = sub { $x-method(a = $array1) }, 'x - (1x100)x200' = sub { $x-method(a = $array100) }, 't - (1)x200' = sub { $t-method(a = $array1) }, 't - (1x100)x200' = sub { $t-method(a = $array100) }, }); BEGIN { package My::Serializer::Array; @My::Serializer::Array::ISA = 'SOAP::Serializer'; sub encode_array { my($self, $array, $name, $type, $attr) = @_; my $items = 'item'; my @items = ($self-encode_object($array-[0], $items)) x @$array; return [$name || '~C:Array', {%{$attr || {}}, '~C:arrayType' = $arraytype, 'xsi:type' = SOAP::Utils::qualify('~C' = $type)}, [@items], $self-gen_id($array)]; } package My::Serializer::XML; @My::Serializer::XML::ISA = 'SOAP::Serializer'; sub encode_array { my($self, $array, $name, $type, $attr) = @_; my $items = join '', 'Array', map("item$_/item", @$array), '/Array'; return [$name, {'_xml' = 1}, $items]; } package My::Serializer::XMLtag; @My::Serializer::XMLtag::ISA = 'SOAP::Serializer'; sub encode_array { my($self, $array, $name, $type, $attr) = @_; my $items = join '', 'Array', map($self-tag('item', {}, $_), @$array), '/Array'; return [$name, {'_xml' = 1}, $items]; } } # -- -- -- -- -- -- -- -- -- -- -- Hope it gives you some ideas. Best wishes, Paul. --- Gunther Birznieks [EMAIL PROTECTED] wrote: At 05:14 PM 2/24/2001 -0800, Paul Kulchenko wrote: That's right, but first Perl caches calls that involve inheritance and second, I use the same scheme, because arrays can have everything inside and I need to call serialization function for every element in array. I did profiling for several versions and did some improvements, but there is no obvious stopper. Is there any way to add an interface to basically provide serialization and deserialization hints? My experience in the way we use SOAP is that there are only a few core objects that really require SOAP and the rest can be on the front-end. Maybe using a CORBA-like IDL config? Thus, I could give a strong hint to
[ANNOUNCE] Apache::SOAP 0.47 (mod_soap)
Apache::SOAP provides SOAP server functionality by simply adding couple of line in .htaccess or .conf file. Based on SOAP::Lite module, hence inherits all functionality, like, for example, compression on wire introduced in last version. For now released as part of SOAP::Lite module. Is there any value to ship it separately (probably as a mod_soap)? Module is available from www.soaplite.com or CPAN. Documentation and examples are included. Any comments are very welcome. Best wishes, Paul. =head1 NAME Apache::SOAP - Provide SOAP server functionality with simple configuration =head1 SYNOPSIS =over 4 =item httpd.conf (Location), directory-based access Location /mod_soap SetHandler perl-script PerlHandler Apache::SOAP PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, Module::Name, Module::method" PerlSetVar options "compress_threshold = 1" /Location =item httpd.conf (Files), file-based access FilesMatch "\.soap$" SetHandler perl-script PerlHandler Apache::SOAP PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, Module::Name, Module::method" PerlSetVar options "compress_threshold = 1" /FilesMatch =item .htaccess, directory-based access SetHandler perl-script PerlHandler Apache::SOAP PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, Module::Name, Module::method" PerlSetVar options "compress_threshold = 1" =back =head1 DESCRIPTION This Apache Perl module provides the ability to add support for SOAP (Simple Object Access Protocol) protocol with easy configuration (either in .conf or in .htaccess file). This functionality should give you lightweight option for hosting SOAP services and greatly simplify configuration aspects. This module inherites functionality from SOAP::Transport::HTTP::Apache component of SOAP::Lite module. =head1 CONFIGURATION The module can be placed in Location, Directory, Files, FilesMatch directives in main server configuration areas or directly in .htaccess file. All parameters should be quoted and can be separated with commas or spaces for lists ("a, b, c") and with 'wide arrows' and commas for hash parameters ("key1 = value1, key2 = value2"). All options that you can find in SOAP::Transport::HTTP::Apache component are available for configuration. Here is the description of most important ones. =over 4 =item dispatch_to (LIST) Specifies path to directory that contains Perl modules you'd like to give access to, or just list of modules (for preloaded modules). PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, Module::Name, Module::method" =item options (HASH) Specifies list of options for your module, for example threshold for compression. Future versions will support more options. See SOAP::Transport::HTTP documentation for other options. PerlSetVar options "compress_threshold = 1" =back =head1 DEPENDENCIES SOAP::Lite mod_perl =head1 SEE ALSO SOAP::Transport::HTTP::Apache for implementation details, SOAP::Lite for general information, and Fexamples/server/mod_soap.htaccess for .htaccess example =head1 COPYRIGHT Copyright (C) 2000-2001 Paul Kulchenko. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHOR Paul Kulchenko ([EMAIL PROTECTED]) =cut __ Do You Yahoo!? Yahoo! Auctions - Buy the things you want at great prices! http://auctions.yahoo.com/
Re: [ANNOUNCE] Apache::SOAP 0.47 (mod_soap)
Hmmm, I am under the impression that the DevelopMentor stuff has a mod_perl SOAP Handler (although I was never able to get it to work) so calling this one Apache::SOAP in the official name space seems a difficult sell unless you are dedicated to supporting the full SOAP API (not sure what SOAP::Lite leaves out). In that case, maybe you should call it Apache::SOAP::Lite rather than Apache::SOAP The benefit of breaking out Apache::SOAP(::Lite) into its own CPAN module is that it will be easier for people to find your module. People who see the APache::* module list and are looking for SOAP will say "Ah ha!" and find out about your SOAP::Lite module and vice versa. It's like getting two directory entries for the price of one. :) The annoying thing about breaking it out in its own module is that you might be tying Apache::SOAP tightly to the version of SOAP::Lite. If you consistently release new versions of both at the same time, then it will be a pain for people to constantly know they have two packages to download instead of one (although I guess it can be bundled). Another positive thing about keeping the bundle under SOAP::Lite is that you might consider releasing SOAP::Lite server code for other persistent engines like PerlEx, Velocigen, SpeedyCGI, etc... and you could eventually add drivers for these in the one package and presumably add SOAP Server code that is shared amongst all the servers instead of breaking them out in different packages. Anyway, all I am saying is that in reply to your question about breaking out Apache::SOAP is ... "It depends". And hopefully these comments will help you decide for yourself what you'd like to do. Thanks, Gunther At 12:42 PM 2/23/2001 -0800, Paul Kulchenko wrote: Apache::SOAP provides SOAP server functionality by simply adding couple of line in .htaccess or .conf file. Based on SOAP::Lite module, hence inherits all functionality, like, for example, compression on wire introduced in last version. For now released as part of SOAP::Lite module. Is there any value to ship it separately (probably as a mod_soap)? Module is available from www.soaplite.com or CPAN. Documentation and examples are included. Any comments are very welcome. Best wishes, Paul. =head1 NAME Apache::SOAP - Provide SOAP server functionality with simple configuration =head1 SYNOPSIS =over 4 =item httpd.conf (Location), directory-based access Location /mod_soap SetHandler perl-script PerlHandler Apache::SOAP PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, Module::Name, Module::method" PerlSetVar options "compress_threshold = 1" /Location =item httpd.conf (Files), file-based access FilesMatch "\.soap$" SetHandler perl-script PerlHandler Apache::SOAP PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, Module::Name, Module::method" PerlSetVar options "compress_threshold = 1" /FilesMatch =item .htaccess, directory-based access SetHandler perl-script PerlHandler Apache::SOAP PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, Module::Name, Module::method" PerlSetVar options "compress_threshold = 1" =back =head1 DESCRIPTION This Apache Perl module provides the ability to add support for SOAP (Simple Object Access Protocol) protocol with easy configuration (either in .conf or in .htaccess file). This functionality should give you lightweight option for hosting SOAP services and greatly simplify configuration aspects. This module inherites functionality from SOAP::Transport::HTTP::Apache component of SOAP::Lite module. =head1 CONFIGURATION The module can be placed in Location, Directory, Files, FilesMatch directives in main server configuration areas or directly in .htaccess file. All parameters should be quoted and can be separated with commas or spaces for lists ("a, b, c") and with 'wide arrows' and commas for hash parameters ("key1 = value1, key2 = value2"). All options that you can find in SOAP::Transport::HTTP::Apache component are available for configuration. Here is the description of most important ones. =over 4 =item dispatch_to (LIST) Specifies path to directory that contains Perl modules you'd like to give access to, or just list of modules (for preloaded modules). PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, Module::Name, Module::method" =item options (HASH) Specifies list of options for your module, for example threshold for compression. Future versions will support more options. See SOAP::Transport::HTTP documentation for other options. PerlSetVar options "compress_threshold = 1" =back =head1 DEPENDENCIES SOAP::Lite mod_perl =head1 SEE ALSO SOAP::Transport::HTTP::Apache for implementation details, SOAP::Lite for general information, and Fexamples/server/mod_soap.htaccess for .htaccess example =head1 COPYRIGHT Copyright (C) 2000-2001 Paul Kulchenko. All rights reserved. This library is free software; you
Re: [ANNOUNCE] Apache::SOAP 0.47 (mod_soap)
Hi, Gunther! --- Gunther Birznieks [EMAIL PROTECTED] wrote: Hmmm, I am under the impression that the DevelopMentor stuff has a mod_perl SOAP Handler (although I was never able to get it to work) so calling this one Apache::SOAP in the official name space seems a difficult sell unless That's true, DM's SOAP module has mod_perl handler, but it's under SOAP::Transport::HTTP::Apache namespace, and SOAP::Lite has also Apache module under the same namespace, but it's just server implementation, and Apache::SOAP's goal is to provide easy access to implementation from configuration files (it is actually subclass of SOAP::Transport::HTTP::Apache). you are dedicated to supporting the full SOAP API (not sure what SOAP::Lite leaves out). First thing I did seven months ago was my email to Keith Brown (author of DM's SOAP/Perl module) about possible ways for cooperation and I'v been told that he's willing to, but design of his module should be consistent with other DM's implementations and he has no plans to change it. There was no easy way to combine our efforts and I came up with another implementation. Don't want to praise myself, but feature set seems to be pretty comparable with other toolkits. I took ::Lite, just because SOAP namespace was already taken. It does much more than you can expect from something with suffix Lite. "Lite suffix reflects number of calories you should spend using this module". In that case, maybe you should call it Apache::SOAP::Lite rather than Apache::SOAP I thought about it, and in fact I released UDDI::Lite, but I also plan to release DBD::SOAP, DBIx::SOAP and couple of other modules and don't want to put suffix Lite everywhere, it could lead to confusion. Also I don't think (IMHO) that DevelopMentor will ever support their module, since they abandon SOAP development in Java, C++ and Perl and there is no other SOAP modules in Perl and I don't have plans to stop development any time soon. Moreover, I have a long TODO list :). find out about your SOAP::Lite module and vice versa. It's like getting two directory entries for the price of one. :) Cool :) The annoying thing about breaking it out in its own module is that you might be tying Apache::SOAP tightly to the version of SOAP::Lite. If you consistently release new versions of both at the same time, then it will be a pain for people to constantly know they have two packages to download instead of one (although I guess it can be bundled). Right, but there is no module specific code (it basically parameters parsing), so I think I'll keep it inside SOAP::Lite for one more version and then release as mod_soap. Another positive thing about keeping the bundle under SOAP::Lite is that you might consider releasing SOAP::Lite server code for other persistent engines like PerlEx, Velocigen, SpeedyCGI, etc... and you could It works actually with Velocigen and as far as I understand with PerlEx also, but I don't have any information about SpeedyCGI. It also provides Daemon, TCP, CGI, IO, POP3 interfaces on server side (in addition to mod_perl and Apache::Registry) as well as COM interface and (hm, did I say already that I don't want to praise myself?) And hopefully these comments will help you decide for yourself what you'd like to do. Definitely, thanks a lot. Best wishes, Paul. __ Do You Yahoo!? Get email at your own domain with Yahoo! Mail. http://personal.mail.yahoo.com/