Dear Monks,

I do not know if this is actually the correct place to write my observations and ask for your questions, so bare with me in case of not correctly posting this question here.

Intro:

I am not expert in scripting or in Perl, I am relative new programmer with a short experience, so my observations maybe are not the most correct ones.

Question:

Why to use Perl with Object Oriented approach?

I found on book Beginning Perl (Programmer to Programmer) written by Simon Cozens and Peter Wainwright. At chapter 11 Object-Oriented Perl the following quotation appears under the subject "Do you need OO?" page 336:

Object-oriented programs run slightly slower than equally-written procedural programs that do the same job, because packaging things into objects and passing objects around is expensive, both in terms of time and resources used. If you can get away without using object orientation, you probably should.

The only the reason that I could come up with is to minimize and simplify the code and maybe, maybe, increase the process speed in some cases.

So in order to understand more about it I created my own experiment with and without Object Oriented approach. I tried to time the performance with assistance of Benchmark Tool.

Process:

I have two identical processes on the same script, on one of them sends the data from main.pl to the MySQL.pm module, the data are processed and send back to the main.pl script. The second process it does exactly the same process but instead of sending the data to another module completes the process on the same script. The purposes creating the same process twice on the same script is to test the execution speeds processes etc. by comparing them.

This is the main.plscript.

#!/usr/bin/perl use strict; use warnings; use MySQL; use DBD::mysql; use Data::Dumper; use Config::Simple; use Benchmark qw(:all); my $path = 'conf.ini'; my $checkExist; my %config; my $count = -5 || die "Need a count!\n"; sub MySQL_OO { my $range = 50; my $minimum = 100; my $random_number = int(rand($range)) + $minimum; my $time = time(); my $object = new MySQL( $time , $random_number ); my @input = $object->getInputDB(); return @input; } sub local_MySQL { Config::Simple->import_from("".$path."", \%config) or die Config::Simple->error(); #my $encrypted = password41($config{'MySQL.pass'}); # for MySQL 4. +1 or my $dbh = DBI->connect("dbi:mysql::".$config{'MySQL.host'}.":".$co +nfig{'MySQL.port'}."", "".$config{'MySQL.user'}."", #"".$encrypted."", "".$config{'MySQL.pass'}."", { 'PrintError' => 1, 'RaiseError' => 1 } ) or die "Could not connect to ". $config{'MySQL.host'} .": ". $DB +I::errstr ."\n"; my $databases = $dbh->do("SHOW DATABASES LIKE '".$config{'MySQL.db +'}."'") or die "Error: " .dbh->errstr. "\n"; if ($databases eq 1) { # printf "Database: ". $config{'MySQL.db'} ." exists not creating: + ". $config{'MySQL.db'} ."\n"; } else { # printf "Database: ". $config{'MySQL.db'} ." does not exist creat +ing: ". $config{'MySQL.db'} ."\n"; $checkExist = $dbh->do("CREATE DATABASE IF NOT EXISTS `".$conf +ig{'MySQL.db'}."`") or die "Could not create the: ".$config{'MySQL.db'}." error: " +. $dbh->errstr ."\n"; } # End of else $dbh->do("USE ".$config{'MySQL.db'}."") or die "Error: " .dbh->errstr. "\n"; my $tables = $dbh->do("SHOW TABLES FROM `".$config{'MySQL.db'}."` +WHERE Tables_in_".$config{'MySQL.db'}." LIKE '".$config{'MySQL.table' +}."'") or die "Error: " .dbh->errstr. "\n"; if ($tables eq 1) { # printf "Table: ".$config{'MySQL.table'}." exists not creating: " +.$config{'MySQL.table'}."\n"; } else { # printf "Table: ".$config{'MySQL.table'}." does not exist creatin +g: ".$config{'MySQL.table'}."\n"; $checkExist = $dbh->prepare("CREATE TABLE IF NOT EXISTS `".$config +{'MySQL.table'}."` ( `id` int(11) NOT NULL AUTO_INCREMENT, `UnixTime` int(11) NOT NULL, `losses` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREM +ENT=1 ;" , { "mysql_use_result" => 1 }); if (!$checkExist->execute()) { die "Error: ". $checkExist->errstr ."\n"; } } # End of else my $range = 50; my $minimum = 100; my $random_number = int(rand($range)) + $minimum; my $time = time(); my @data = ($time,$random_number); $checkExist = $dbh->prepare("INSERT IGNORE INTO `".$config{'MySQL. +table'}."` (`UnixTime`, `losses`) VALUES ('".$time."','".$random_numb +er."')" , { "mysql_use_result" => 1 }); if (!$checkExist->execute()) { die "Error: ". $checkExist->errstr ."\n"; } $checkExist->finish(); $dbh->disconnect(); return @data; } # End of mysql sub my $r = timethese ( $count , { 'MySQL_OO' => '&MySQL_OO', 'local_MySQL' => '&local_MySQL' } ); cmpthese $r; #print "This is the time from \@result: ".$result[0]."\n"; #print "This is the random_number from \@result: ".$result[1]."\n"; 1;

This is the MySQL.pm module which processes the data.

#!/usr/bin/perl use strict; use warnings; use DBD::mysql; use Config::Simple; $|=1; #flush every time the program my $path = 'conf.ini'; my $checkExist; my %config; package MySQL; sub new { Config::Simple->import_from("".$path."", \%config) or die Config::Simple->error(); #my $encrypted = password41($config{'MySQL.pass'}); # for MySQL 4. +1 or my $dbh = DBI->connect("dbi:mysql::".$config{'MySQL.host'}.":".$co +nfig{'MySQL.port'}."", "".$config{'MySQL.user'}."", #"".$encrypted."", "".$config{'MySQL.pass'}."", { 'PrintError' => 1, 'RaiseError' => 1 } ) or die "Could not connect to ". $config{'MySQL.host'} .": ". $DB +I::errstr ."\n"; my $databases = $dbh->do("SHOW DATABASES LIKE '".$config{'MySQL.db +'}."'") or die "Error: " .dbh->errstr. "\n"; if ($databases eq 1) { # printf "Database: ". $config{'MySQL.db'} ." exists not creating: + ". $config{'MySQL.db'} ."\n"; } else { # printf "Database: ". $config{'MySQL.db'} ." does not exist creat +ing: ". $config{'MySQL.db'} ."\n"; $checkExist = $dbh->do("CREATE DATABASE IF NOT EXISTS `".$conf +ig{'MySQL.db'}."`") or die "Could not create the: ".$config{'MySQL.db'}." error: " +. $dbh->errstr ."\n"; } # End of else $dbh->do("USE ".$config{'MySQL.db'}."") or die "Error: " .dbh->errstr. "\n"; my $tables = $dbh->do("SHOW TABLES FROM `".$config{'MySQL.db'}."` +WHERE Tables_in_".$config{'MySQL.db'}." LIKE '".$config{'MySQL.table' +}."'") or die "Error: " .dbh->errstr. "\n"; if ($tables eq 1) { # printf "Table: ".$config{'MySQL.table'}." exists not creating: " +.$config{'MySQL.table'}."\n"; } else { # printf "Table: ".$config{'MySQL.table'}." does not exist creatin +g: ".$config{'MySQL.table'}."\n"; $checkExist = $dbh->prepare("CREATE TABLE IF NOT EXISTS `".$config +{'MySQL.table'}."` ( `id` int(11) NOT NULL AUTO_INCREMENT, `UnixTime` int(11) NOT NULL, `losses` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREM +ENT=1 ;" , { "mysql_use_result" => 1 }); if (!$checkExist->execute()) { die "Error: ". $checkExist->errstr ."\n"; } } # End of else my $class = shift; my $data = { _time => shift, _random_number => shift, }; # Print all the values just for clarification. #print "Time is $data->{_time}\n"; #print "Random Number is $data->{_random_number}\n"; bless $data, $class; $checkExist = $dbh->prepare("INSERT IGNORE INTO `".$config{'MySQL. +table'}."` (`UnixTime`, `losses`) VALUES ('".$data->{_time}."','".$da +ta->{_random_number}."')" , { "mysql_use_result" => 1 }); if (!$checkExist->execute()) { die "Error: ". $checkExist->errstr ."\n"; } $checkExist->finish(); $dbh->disconnect(); return $data; } # End of mysql sub sub getInputDB { my ( $data ) = @_; return $data->{_time} , $data->{_random_number}; } 1;

I am also including the conf.ini file in case that someone want to replicate the experiment.

[MySQL] user=******** pass=******** host=localhost port=3306 db=Speed table=Data

Results

I contact the experiment 4 times to get different results and observe the output.

Output straight from my terminal:

Benchmark: running MySQL_OO, local_MySQL for at least 5 CPU seconds... MySQL_OO: 186 wallclock secs ( 4.69 usr + 0.77 sys = 5.46 CPU) @ 5 +63.92/s (n=3079) local_MySQL: 196 wallclock secs ( 4.78 usr + 0.79 sys = 5.57 CPU) @ +608.98/s (n=3392) Rate MySQL_OO local_MySQL MySQL_OO 564/s -- -7% local_MySQL 609/s 8% -- tiny@OS:~/Desktop/PeRl_MySQL$ perl main.pl Benchmark: running MySQL_OO, local_MySQL for at least 5 CPU seconds... MySQL_OO: 182 wallclock secs ( 4.55 usr + 0.72 sys = 5.27 CPU) @ 6 +16.89/s (n=3251) local_MySQL: 186 wallclock secs ( 5.00 usr + 0.82 sys = 5.82 CPU) @ +565.98/s (n=3294) Rate local_MySQL MySQL_OO local_MySQL 566/s -- -8% MySQL_OO 617/s 9% -- tiny@OS:~/Desktop/PeRl_MySQL$ perl main.pl Benchmark: running MySQL_OO, local_MySQL for at least 5 CPU seconds... MySQL_OO: 155 wallclock secs ( 4.33 usr + 0.73 sys = 5.06 CPU) @ 5 +58.10/s (n=2824) local_MySQL: 172 wallclock secs ( 4.45 usr + 0.76 sys = 5.21 CPU) @ +558.73/s (n=2911) Rate MySQL_OO local_MySQL MySQL_OO 558/s -- -0% local_MySQL 559/s 0% -- tiny@OS:~/Desktop/PeRl_MySQL$ perl main.pl Benchmark: running MySQL_OO, local_MySQL for at least 5 CPU seconds... MySQL_OO: 163 wallclock secs ( 4.41 usr + 0.72 sys = 5.13 CPU) @ 5 +47.56/s (n=2809) local_MySQL: 162 wallclock secs ( 4.55 usr + 0.75 sys = 5.30 CPU) @ +541.89/s (n=2872) Rate local_MySQL MySQL_OO local_MySQL 542/s -- -1% MySQL_OO 548/s 1% --

Observations

On the first run the results is as expected, the Object Oriented process was slower by 7%.

The impressive part one the rest of the rounds. It actually shows that the Object Oriented process is almost fast as the normal process and at some point it is even faster!

Conclusions

The book was written back on 2000, fourteen years ago. From my point of view Object Oriented programming is a huge advantage, it makes the code shorter and also possibly faster on some occasions.

So in conclusion, when a user should choose to follow an Object Oriented programming approach if the code is really long only?

Thank you all for your time and effort to assist me with my question/discussion.

Seeking for Perl wisdom...on the process...not there...yet!

In reply to When to Use Object Oriented approach in Perl? (RFC) by thanos1983

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.