Loading ...
Sorry, an error occurred while loading the content.

272SOAP::Serializer::envelope

Expand Messages
  • Douglas Bonar
    Apr 30, 2001
    • 0 Attachment
      Some use around here indicated that using SOAP-Lite just
      as a way to construct SOAP messages for a non-Perl server
      is slow. (This is cases where we have explicit message
      templates we want to construct, rather than taking advantage
      of SOAP-Lite's strength at automarshalling the arguments
      and return values from Perl functions.) Looking at some
      DProf results, it appeared that one of the main reasons
      is that SOAP-Lite spends a fair chunk of time in parsing
      some boilerplate Envelope/Header/Body parts of the message
      structure.

      As a test example, I built a simple soap message three
      different ways.

      The first way (labeled 'mine' below) was with a module I wrote
      for the purpose. Basically it lets you specify your elements,
      their values and attributes and their relationships. It then
      translates that into XML and wraps it in a simple Envelope/Header/
      Body construct. There is nothing automagic in the module. It is
      only one step above putting the messages in here documents, but
      is fairly fast.

      The second way ('freeform') was to use the above module to
      build the body of the message and then passing that to SOAP-Lite
      asking it to make a freeform message (of type 'xml') out of
      that string. That way SOAP-Lite isn't doing any parsing of
      my data, only its own.

      The final way was to build my data with SOAP::Data elements.
      This is the way I would prefer to construct the messages. In
      the resulting code, it looks about the same as using the special
      purpose test module. Internally though this is more likely
      to do the right thing is special cases.


      5 methods, 100 message builds of a fairly simple message.
      The system time was about the same for all cases. There is
      no transport or message parsing going on.

      Method User Time Relative Comments encode_object
      ========================================================
      mine 1.91 sec 100% reference 0/mes.

      freeform 4.64 sec 243% 10/mes.
      method 5.65 sec 296% 14/mes.

      freeform' 3.30 sec 173% 29% savings 3/mes.
      method' 4.38 sec 229% 22% savings 7/mes.


      The 'correct' way is almost 3 times slower than the special
      purpose building. And the number of calls to the
      SOAP::Serializer::encode_object method per message created
      is quite high. In fact, even if I provde the XML string with
      all the real content there are still 10 calls to encode_object.

      Looking at SOAP::Serializer::envelope, it was clear that the
      many of the calls are there because of the method builds the
      message internally by calls to encode_object. The structure
      of those calls is the same every time though, it is just boilerplate.
      "Unrolling" that code (see below) gave the primed results in
      the table above. 20% savings on a small message (obviously
      proportionally less on a large message). Given that many
      SOAP messages probably are small, that's not too bad.

      I think the change doesn't interfer with anything else in
      the module. The results from my test cases are identical
      message with either the old or new code.

      Doug



      The change (in SOAP::Serializer::envelope):

      my ($encoded) = $self->encode_object(
      SOAP::Data->name('~V:Envelope' => \SOAP::Data->value(
      SOAP::Data->name('~V:Header' => \$header),
      SOAP::Data->name('~V:Body' => \$body)
      ))->attr($self->attr)
      );

      became

      my $encoded;
      if (0) {
      ($encoded) = $self->encode_object(
      SOAP::Data->name('~V:Envelope' => \SOAP::Data->value(
      SOAP::Data->name('~V:Header' => \$header),
      SOAP::Data->name('~V:Body' => \$body)
      ))->attr($self->attr)
      );
      } else {
      ($encoded) = (['~V:Envelope',
      $self->attr,
      [ [ '~V:Header',{}, [ $self->encode_object($header) ],
      0 ],
      [ '~V:Body', {}, [ $self->encode_object($body) ], 0
      ]
      ],
      0]);
      }
    • Show all 3 messages in this topic