[Wellington-pm] comparison and assignment: insignificant optimisation

Kent Fredric kentfredric at gmail.com
Mon Jun 16 06:35:08 PDT 2014


On 16 June 2014 23:09, Olly Betts <olly at survex.com> wrote:

> A Perl scalar holding a string knows the string's length (it doesn't do
> something like calling C's strlen() function each time - it can't as the
> string might contain zero bytes) so length($foo) just loads a value from
> a field in a C structure to get the length.  It may need to turn the
> scalar into a string first, but if you call it more than once, only
> the first call should need to do that.
>


Indeed:


perl  -MO=Concise -e'my $var = q[hello]; length($var)'
9  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
5     <2> sassign vKS/2 ->6
3        <$> const(PV "hello") s ->4
4        <0> padsv[$var:1,2] sRM*/LVINTRO ->5
6     <;> nextstate(main 2 -e:1) v:{ ->7
8     <1> length[t2] vK/1 ->9
7        <0> padsv[$var:1,2] s ->8


perl  -MO=Concise,-exec -e'my $var = q[hello]; length($var)'
1  <0> enter
2  <;> nextstate(main 1 -e:1) v:{
3  <$> const(PV "hello") s
4  <0> padsv[$var:1,2] sRM*/LVINTRO
5  <2> sassign vKS/2
6  <;> nextstate(main 2 -e:1) v:{
7  <0> padsv[$var:1,2] s
8  <1> length[t2] vK/1
9  <@> leave[1 ref] vKP/REFC


perl -MDevel::Peek -e'my $var = q[hello]; print Dump $var; $var .=
q[world]; print Dump $var'

SV = PV(0x2559d80) at 0x2579778
  REFCNT = 1
  FLAGS = (PADMY,POK,IsCOW,pPOK)
  PV = 0x257f800 "hello"\0
  CUR = 5
  LEN = 10
  COW_REFCNT = 1
SV = PV(0x2559d80) at 0x2579778
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x25686a0 "helloworld"\0
  CUR = 10
  LEN = 16


Note value of CUR

length() does involve a fair amount of low-level jumping, but its more or
less a plumbing route that ends up returning the value of CUR

https://metacpan.org/source/RJBS/perl-5.20.0/pp.c#L2933

https://metacpan.org/source/RJBS/perl-5.20.0/sv.c#L6849

https://metacpan.org/source/RJBS/perl-5.20.0/sv.h#L1666

https://metacpan.org/source/RJBS/perl-5.20.0/sv.h#L1176

https://metacpan.org/source/RJBS/perl-5.20.0/sv.h#L469

Just the question is: Does all that cost more  than creating a variable,
assigning it, then re-reading it or not?

That is why its better to optimise based on measured data than hypothesis
:)

---

use strict;
use warnings;
use utf8;

use Benchmark qw( :all :hireswallclock );

cmpthese(
    -10,
    {
        '2x length' => sub {
            my $value = q[Hello World];
            for ( 0 .. 2000 ) {
                my $initial = 0;
                if ( length($value) > $initial ) {
                    $initial = length($value);
                }
            }
        },
        'tempvar' => sub {
            my $value = q[Hello World];
            for ( 0 .. 2000 ) {
                my $initial = 0;
                if ( ( my $temp = length($value) ) > $initial ) {
                    $initial = $temp;
                }
            }
          }
    }
);

---

            Rate   tempvar 2x length
tempvar   2323/s        --      -22%
2x length 2966/s       28%        --
--

Guess it wasn't worth the effort.

-- 
Kent
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/wellington-pm/attachments/20140617/06877f30/attachment.html>


More information about the Wellington-pm mailing list