One interesting thing is how if,elsif,esle are executed. Take a look in this code:
You can see that only the first sub (testA) is executed. (try to change || to &&). This show that in the conditions of if|elsif is good to put first the most simple codes. For example, if you have:if ( &testA || &testB ) { print "IF\n" ;} sub testA { print "AAA\n" ; return( 1 ) ;} sub testB { print "BBB\n" ; return( 1 ) ;}
Was not write in the best way! First, the -s need to be the last, because we can avoid the query in the HD. the eq need to be the first, since is more easy to process than a regexp.if ( -s $file || $file =~ /\.new$/ || $file eq 'foo ') { ;}
We need to know how our script is executed too. First Perl get your file, read it byte by byte and parse it, optimize your code and create the bytecode, and than the bytecode is executed.
The optimize stage is very interesting. In this point numbers will be calculated, for example, if your have 1024*8, will be converted to 8192, in other words, write 1024*8 or 8192 inside a loop that will be runned 1000 times don't change the speed of the script.
Null blocks, like if (0) {} is cuted off from the code. One good thing is to test your code with a deparse rotine to see what Perl do:
use B::Deparse; my $deparse = B::Deparse->new("-s"); $body = $deparse->coderef2text(\&func); print "$body\n" ; sub func { if (0) { print "null\n" ;} print "aaa \" $var bbb\n" ; return( 'foo' ) ; }
Other thing is varialbes. Always try to use them in this order SCALAR , ARRAY & HASH. You will save memory and CPU. Other thing is how to work with them, for example:
This is wrong, because you are rewriting all the varialbe to just append the ",bar" in the end! The right is:$var = "foo" ; $var = "$var,bar" ;
This will just append the new data in the end. You can do the same thing for other operators:$var = "foo" ; $var .= ",bar" ;
Now how to insert data in the begin? Most peoples do:$var += 10 ; # for $var = $var + 10 ; $var -= 10 ; # for $var = $var - 10 ; $var /= 10 ; # ... $var *= 10 ; # ...
But the best way is:$var = "foo$var" ;
This not rewrite all the variable!substr($var,0,0) = "foo" ;
Other thing is the "my". Use it! (use strict too, at least in the development stage). "my" is very good, 1st you don't get conflict with variables with the same name, and it cleans the memory after use the variable (when you go out of a block). But if you have a loop that will be runned many times don't do:
If you can do:while(1){ my $var = &foo() ; ... }
Why this? Well, if you put the my inside, you set the my, write the variable, run the code, than clean the variable to recreate it in the next loop. If you put outside, you create it only 1 time, than only write to the variable, and this use less CPU. And don't forget, generally we use a lot of variables inside a loop, and is in this point that make difference.my $var ; while(1){ $var = &foo() ; ... }
Now how to paste variables. If you have a big variable, let's say with the content of a file, and you need to paste it to a sub. Paste the reference, or you will use more memory duplicating the varialbe inside the loop:
$data = 'foo' x (1024*1024) ; &test(\$data) ; sub test { my ( $datarf ) = @_ ; if ( $$datarf =~ /foo/s ) { print "bar\n" ;} };
But to use references you need to know how to work with them! to paste use:
To access:$rf_s = \$scalar ; $rf_a = \@array ; $rf_h = \%hash ;
$$rf_s .= 'foo' ; push(@$rf_a , "BAR") ; $$rf_a[0] = 'bar' ; $$rf_h{b} = 'foo' ; foreach my $Key ( keys %{$rf_h} ) { my $Value = $$rf_h{$Key} ; print "$Key = $Value\n" ; }
About files, 1st, if you are using files like a database, see DBD::CSV and DBD::SQLite, they are very good for db files. But if you want to read don't use <FOO>, specially for big files:
<FOO> will read the file, but will look for the \n sinde it too, and this is slow! Use this:open (FLHD,"$0") ; my $fl_data = join('' , <FLHD>) ;
open (FLHD,"$0") ; my $fl_data ; 1 while( sysread(FLHD, $fl_data , 1024*8 , length($fl_data) ) ) ;
Other thing, if you want to process the lines, don't cat all the file inside a @array, to after this process them! Is better to read and process, this is faster and use less memory:
open (FLHD,"$0") ; while (my $line = <FLHD>) { my ($x , $y , $z) = split("::" , $line) ; }
And to finsih, a funy way to clone (link) the access to variables:
$foo = '123' ; $bar = undef ; *bar = \$foo ; print "bar: $bar\n" ; $bar = 102030 ; print "foo: $foo\n" ;
And you can do this for any type:
# To have $bar , @bar and %bar from *foo ; *bar = \$foo ; *bar = \@foo ; *bar = \%foo ; # glob: (but doesn't work for tied handles!) *bar = *foo ; # For packages: *bar:: = *foo:: ; # you have now main::bar linked to main::foo
But always remmember, only spent time optimizing your code in areas that will be executed a lot of times, specially inside loops.
And don't make code optimization a jail. Perl is wonderful because we are free to do our code how we want, with OO or not, in packages or not, with my, strict... And this is very good, because let us free to be creative! Don't falls in the idea that codes with a lot of rules to make it understandable by others is very good. Weel, don't make a trash, but codes like Java (with all the respect) make us to spent much time following the rules, and we don't have time and dynamism to be creative to make codes with good ideas! And don't forget, the final objective is important, not only the theory or ilusion that much peoples create! Like Java, that have a very good idea, portable codes and good OO, but if it's very slow, we lost the objective, make a program that works!
We can see now a lot of work to make rules for codes. To get companys certified. To follow the herd of buffalos. Well code rules are good, but we can't cut the creativity! Make rules only to can reuse the code by others, and treat peoples like machines, that can be replaced, that will make the things always in the same way, is not the right! Don't buy this idea! Id don't do this for who works for me, because I don't want this for me!
The last tip, each time is different of other, don't think that the same recipe is for all the time. You always need to see where you are, what you have, and who are with you. When you gonna make the rules of a project, let the programmers do this! Only them know what they know, what resources they can use or like to use, and the group will work very well!
Like a famous song in Bra(s|z)il ("Lulu Santos - Como Uma Onda.mp3"):
ENGLISH Nothing that was will be Again in the same way like was one day. Everything goes, Everything will always go. The life comes in waves Like a sea, In a infinity coming and going. Everything that it is seen is not Equal than what we saw one second ago, Everything change all the time In the world. Don't try to run away Even lie for your self, now, Exist so much life out there, Inside here, always, Like a wave in the sea. PORTUGUESE: Nada do que foi será De novo do jeito que já foi um dia. Tudo passa, Tudo sempre passará. A vida vem em ondas Como um mar, Num indo e vindo infinito. Tudo que se vê não é Igual ao que a gente viu há um segundo, Tudo muda o tempo todo No mundo. Não adianta fugir Nem mentir pra si mesmo, agora, Há tanta vida lá fora, Aqui dentro, sempre, Como uma onda no mar.
Enjoy. Send your feedback, and other tips! ;-P
Graciliano M. P.
"The creativity is the expression of the liberty".
|
---|