Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

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

by HugoNo1 (Novice)
on Sep 26, 2018 at 18:34 UTC ( #1223092=note: print w/replies, xml ) Need Help??


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

According to the official Documentation on

https://perldoc.perl.org/perlperf.html#Assigning-and-Dereferencing-Variables.
> The difference is clear to see and the dereferencing approach is slower.

Dereferencing Variables is slower than Passing the References through.

Therefore a Code like:

package MyClass1; sub newFunctionName { #Doing my stuff } sub oldFunctionName { my $self = shift; $self->newFunctionName(@_); }

As you would do it in other Programming Languages. Will be slower than the goto Implementation:

package MyClass2; sub newFunctionName { #Doing the stuff } sub oldFunctionName { goto &newFunctionName; }

That is what I exactly was looking for but couldn't find any concrete Example for it.

This makes Sense because in the MyClass1::oldFunctionName() implemention the $self variable must be created in memory first which consumes CPU Processing Time.
Which is confirmed by the official Documentation.

Replies are listed 'Best First'.
Re^4: Number of times I've used goto in Perl
by Eily (Monsignor) on Sep 27, 2018 at 00:15 UTC

    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.

      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.

Re^4: Number of times I've used goto in Perl
by Anonymous Monk on Sep 26, 2018 at 20:12 UTC
    87 core Perl (5.28.0) modules (out of 650) use goto 253 times:
    
    _charnames
    Archive::Tar
    attributes
    autodie
    autodie::Util
    AutoLoader
    AutoSplit
    autouse
    B
    B::Concise
    B::Deparse
    B::Op_private
    bytes
    Class::Struct
    Compress::Raw::Bzip2
    Compress::Raw::Zlib
    Config
    CPAN
    CPAN::Distribution
    DB_File
    Devel::Peek
    Devel::PPPort
    diagnostics
    DynaLoader
    Encode
    Exporter
    ExtUtils::CBuilder::Base
    ExtUtils::Command::MM
    ExtUtils::Constant
    ExtUtils::Liblist
    ExtUtils::MM_VMS
    Fatal
    fields
    File::Compare
    File::Copy
    File::DosGlob
    File::Glob
    File::Path
    File::stat
    Filter::Simple
    Getopt::Long
    Hash::Util
    if
    IO::Select
    IO::Socket::IP
    IO::Uncompress::Base
    IPC::SysV
    List::Util
    Locale::Codes::Language_Codes
    Memoize
    Module::Load
    mro
    Net::FTP
    Net::hostent
    Net::netent
    Net::protoent
    Net::servent
    ok
    Opcode
    open
    Pod::Functions
    Pod::Simple::BlackBox
    Pod::Simple::LinkSection
    POSIX
    SelfLoader
    sigtrap
    strict
    Sys::Syslog
    TAP::Parser
    TAP::Parser::Aggregator
    TAP::Parser::Result::Test
    Term::ANSIColor
    Term::Cap
    Test2::EventFacet::Meta
    Test2::IPC
    Test::Tester
    Test::Tester::Delegate
    Text::Balanced
    threads
    Tie::Memoize
    Time::HiRes
    Unicode::UCD
    User::grent
    User::pwent
    utf8
    warnings
    XSLoader
    

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (7)
As of 2019-10-22 06:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?