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

Arrays of arrays

Expand Messages
  • teden
    Folks, A little while back, I posted a question about processing arrays of arrays, and got some great help from Duncan Cameron. The suggested solution was
    Message 1 of 2 , Nov 6, 2003
    • 0 Attachment
      Folks,

      A little while back, I posted a question about processing arrays of
      arrays, and got some great help from Duncan Cameron. The suggested
      solution was something like this:

      my $som = SOAP::Deserializer->deserialize($xml);
      # Iterate through all child elements of <person>
      for (my $i = 1; my $a = $som->dataof("//person/[$i]"); $i++) {
      ...
      for (my $j = 1; my $b = $som->dataof("//person/[$i]/[$j]"); $j++) {
      ...
      }
      }

      However, I found that this was sloooooow since every loop through you
      had to perform a $som->dataof which was exceedingly expensive. I
      rewrote it like so:

      my $som = SOAP::Deserializer->deserialize($xml);
      my $i = 0;
      foreach my $a ($som->dataof("//person/*")) {
      $i++;
      my $j = 0;
      foreach my $b ($som->dataof("//person/[$i]/*")) {
      $j++;
      ...
      }
      }

      and it runs significantly faster. Just thought you all might like to
      know...

      Thom Eden
    • Duncan Cameron
      ... That s a good spot, I wondered if there was a better (= quicker) way to iterate. Just out of interest I benchmarked four approaches the original one that I
      Message 2 of 2 , Nov 6, 2003
      • 0 Attachment
        At 16:46:38 on 2003-11-06 teden <the@...> wrote:

        >Folks,
        >
        >A little while back, I posted a question about processing arrays of
        >arrays, and got some great help from Duncan Cameron. The suggested
        >solution was something like this:
        >
        >my $som = SOAP::Deserializer->deserialize($xml);
        ># Iterate through all child elements of <person>
        >for (my $i = 1; my $a = $som->dataof("//person/[$i]"); $i++) {
        >...
        >for (my $j = 1; my $b = $som->dataof("//person/[$i]/[$j]"); $j++) {
        >...
        >}
        >}
        >
        >However, I found that this was sloooooow since every loop through you
        >had to perform a $som->dataof which was exceedingly expensive. I
        >rewrote it like so:
        >
        >my $som = SOAP::Deserializer->deserialize($xml);
        >my $i = 0;
        >foreach my $a ($som->dataof("//person/*")) {
        >$i++;
        >my $j = 0;
        >foreach my $b ($som->dataof("//person/[$i]/*")) {
        >$j++;
        >...
        >}
        >}
        >
        >and it runs significantly faster. Just thought you all might like to
        >know...
        >
        That's a good spot, I wondered if there was a better (= quicker) way to
        iterate. Just out of interest I benchmarked four approaches
        the original one that I suggested
        your improvement
        using XML::XPath
        using XML::LibXML

        Basically putting your code in a subroutine and using Benchmark to time
        1000 iterations gave these results

        XML::LibXML:
        1 wallclock secs ( 1.10 usr + 0.00 sys = 1.10 CPU) @ 909.09/s (n=1000)
        Improved:
        11 wallclock secs (10.71 usr + 0.00 sys = 10.71 CPU) @ 93.37/s (n=1000)
        XML::XPath:
        16 wallclock secs (15.92 usr + 0.00 sys = 15.92 CPU) @ 62.81/s (n=1000)
        Original:
        20 wallclock secs (19.89 usr + 0.00 sys = 19.89 CPU) @ 50.28/s (n=1000)

        LibXML is way faster so you may want to consider using that if you
        are doing a lot of navigation through the SOAP message, but note that
        these figures don't include the time to load the module.

        Regards
        Duncan
      Your message has been successfully submitted and would be delivered to recipients shortly.