Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re^4: Number of times I've used goto in Perl

by Eily (Monsignor)
on Sep 27, 2018 at 00:15 UTC ( [id://1223116]=note: print w/replies, xml ) Need Help??


in reply to Re^3: Number of times I've used goto in Perl
in thread Number of times I've used goto in Perl

That doesn't contradict my point, which was that goto has 3 effects: transmitting @_ directly, removing the current function from the call stack and clearing the effect of local. If all you want to do is jump to another function without touching @_, this can be done like this:

sub oldFunctionName { &newFunctionName; }
I have quoted the relevant documentation in my previous post.

Besides, since goto does this extra work, I wouldn't be confident about saying that it uses less CPU. Also perl does plenty of things under the hood, and the documentation calls it "magic". I would never conclude that a feature takes less CPU time based on the description of what it does alone.

There is no dereferencing in your code though, dereferencing would like one of those lines:

$$self; ${$self}; @{$self}; %{$self}; $self->{Key}; $self->[0];
Sadly the syntax for a method call works only on (some) references, and also uses the arrow operator ( -> ) so it's quite confusing.

Replies are listed 'Best First'.
Re^5: Number of times I've used goto in Perl
by HugoNo1 (Novice) on Oct 03, 2018 at 09:54 UTC

    I wrote a little benchmark test to check the performance of different implementations

    package MyClass1;
    
    sub new
    {
      my $invocant = shift;
      my $class    = ref($invocant) || $invocant;
      my $self     = undef;
    
    
        #Set the Default Attributes and assign the initial Values
        $self = {
            "_report" => "",
            "_count" => 0
        };
    
    
        #Bestow Objecthood
        bless $self, $class;
    
    
        #Give the Object back
        return $self;
      
    }
    
    sub newFunctionName
    {
      my $self = shift;
      
      $self->{"_count"} = shift;
      $self->{"_report"} = __PACKAGE__ . " - run no. '" . $self->{"_count"} . "'\n";
    }
    
    sub oldFunctionName
    {
      my $self = shift;
      
      $self->newFunctionName(@_);
    }
    
    
    package MyClass2;
    
    sub new
    {
      my $invocant = shift;
      my $class    = ref($invocant) || $invocant;
      my $self     = undef;
    
    
        #Set the Default Attributes and assign the initial Values
        $self = {
            "_report" => "",
            "_count" => 0
        };
    
    
        #Bestow Objecthood
        bless $self, $class;
    
    
        #Give the Object back
        return $self;
      
    }
    
    sub newFunctionName
    {
      my $self = shift;
      
      $self->{"_count"} = shift;
      $self->{"_report"} = __PACKAGE__ . " - run no. '" . $self->{"_count"} . "'\n";
    }
    
    sub oldFunctionName
    {
      goto &newFunctionName;
    }
    
    
    package MyClass3;
    
    sub new
    {
      my $invocant = shift;
      my $class    = ref($invocant) || $invocant;
      my $self     = undef;
    
    
        #Set the Default Attributes and assign the initial Values
        $self = {
            "_report" => "",
            "_count" => 0
        };
    
    
        #Bestow Objecthood
        bless $self, $class;
    
    
        #Give the Object back
        return $self;
      
    }
    
    sub newFunctionName
    {
      my $self = shift;
      
      $self->{"_count"} = shift;
      $self->{"_report"} = __PACKAGE__ . " - run no. '" . $self->{"_count"} . "'\n";
    }
    
    sub oldFunctionName
    {
      &newFunctionName;
    }
    
    
    package main;
    
    use Benchmark;
    
         
    my $o1 = MyClass1->new;
    my $o2 = MyClass2->new;
    my $o3 = MyClass3->new;
    my $icnt = 0;
    
         
         
    print "count 0: '$icnt':\n";
    
    print "o1 report 0 (count: '" . $o1->{"_count"} . "'): '" . $o1->{"_report"} . "'\n";
    print "o2 report 0 (count: '" . $o2->{"_count"} . "'): '" . $o2->{"_report"} . "'\n";
    print "o3 report 0 (count: '" . $o3->{"_count"} . "'): '" . $o3->{"_report"} . "'\n";
    
     timethese( 10000000, {
     'MyClass1'  => sub { 
     
     $icnt = 0 if($o1->{"_count"} == 0);
     
     $icnt++;
     $o1->oldFunctionName($icnt);
     
    
    },
     'MyClass2'  => sub { 
    
     $icnt = 0 if($o2->{"_count"} == 0);
     
     $icnt++;
     $o2->oldFunctionName($icnt);
    
    
     },
     'MyClass3'  => sub { 
    
     $icnt = 0 if($o3->{"_count"} == 0);
     
     $icnt++;  
     $o3->oldFunctionName($icnt);
    
    
     },
     });
    
         
    print "count 0: '$icnt':\n";
    
    print "o1 report 0 (count: '" . $o1->{"_count"} . "'): '" . $o1->{"_report"} . "'\n";
    print "o2 report 0 (count: '" . $o2->{"_count"} . "'): '" . $o2->{"_report"} . "'\n";
    print "o3 report 0 (count: '" . $o3->{"_count"} . "'): '" . $o3->{"_report"} . "'\n";
    

    The test result was:

    count 0: '0':
    o1 report 0 (count: '0'): ''
    o2 report 0 (count: '0'): ''
    o3 report 0 (count: '0'): ''
    Benchmark: timing 10000000 iterations of MyClass1, MyClass2, MyClass3...
      MyClass1:  8 wallclock secs ( 7.48 usr +  0.00 sys =  7.48 CPU) @ 1336898.40/s (n=10000000)
      MyClass2:  7 wallclock secs ( 6.61 usr +  0.00 sys =  6.61 CPU) @ 1512859.30/s (n=10000000)
      MyClass3:  6 wallclock secs ( 5.96 usr +  0.00 sys =  5.96 CPU) @ 1677852.35/s (n=10000000)
    count 0: '10000000':
    o1 report 0 (count: '10000000'): 'MyClass1 - run no. '10000000'
    '
    o2 report 0 (count: '10000000'): 'MyClass2 - run no. '10000000'
    '
    o3 report 0 (count: '10000000'): 'MyClass3 - run no. '10000000'
    '
    

    I repeated the test several times and it gives always the same result pattern.
    - The slowest performant implementation is MyClass1 with the $self->newFunctionName(@_); call
    - The MyClass2::oldFunctionName() implementation with the goto statement performs already better.
    - But the best performance is achieved with the MyClass3::oldFunctionName() implementation with the &newFunctionName; call

    I didn't know this possible Syntax yet.
    So thank you very much!

      You're welcome :)

      Also for your information, I'm guessing you are getting your markup by looking for HTML tags on another site. There is a perlmonks specific list here: Markup in the Monastery
      One of the differences is that you can use <c> rather than <pre>. It's shorter, and it adds a "download" link for people who want to test your code.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1223116]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (5)
As of 2024-04-18 02:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found