SlideShare a Scribd company logo
对Perl程序员的忠告
                                                                 • 区分$, @, %, 函数后的括号可以省略
                                                                 • 和C语言的一些区别:
           Perl语言高级编程专题                                              – 类型的多态性
                                                                     – 没有malloc/free的困扰
                Lesson 10
                                                                     – $a || $b不返回布尔值,返回$a或$b之一的值
                                                                     – ? : 可以是左值: ($flag ? $a : $b) = 6;
                       周晓方
                                                                     – 没有struct,union,switch等
              courses@xfzhou.homeftp.org                             – C的i[a]和a[i]等价,perl不是

          Perl调试技巧
          (Peter Scott, Ed Wright, "Perl Debugged")     1                                                                                          2




                      资源的优化                                                  语义(理解上的差别)
• 首先确保可读性和可维护性 (据Moore's law)                                    • 语义错误:open (A, 'f) | die "Error";
• 利用任务管理器查看内存占用情况,用                                              • 语义错误:printf "Number of @a = %d", @a;
  Benchmark,Devel::DProf确定运行的时间                                  • 用B::Deparse查看perl对代码的理解
                                                                   Deparse还很简陋,但遇到了奇怪现象,可以单独拿
• 及早结束循环:循环体开头合理增加next/last                                        出来试一试
• 尽量避免调用外部程序,避免` `或system( )                                     perl -MO=Deparse -e "for ($i=1;$i<10;$i++) {$j+=$i;}"
                                                                 for ($i = 1; $i < 10; ++$i) {
• 节约内存:优先用数组,再hash,最后标量                                              $j += $i;
                                                                 }
• 空间换速度:Memoize模块,记住已有调用                                         -e syntax OK

• 速度换空间:大hash用tie函数关联到数据库                                        perl -MO=Deparse -e "use strict my $a = 1; print $a; exit;"
                                                                 print $a;
                                                                 exit;
                                                        3        -e syntax OK                                                                      4



                                                                     –L    列出所有的断点                        $i is 5, $j is 15
                     perl的调试器                                        –t    跟踪执行
                                                                                                          $i is 6, $j is 21
                                                                                                          $i is 7, $j is 28
                                                                                                          main::(C:bug.pl:6):            print
• perl -d myscripts.pl                                      1
                                                            2
                                                                  #!/usr/bin/perl -wd
                                                                  use strict;
                                                                                                          "$i is $i, $j is $jn";
                                                                                                            DB<2> t
    –   s     Step 运行一行,跟踪进入子程序                             3
                                                            4
                                                                  my $j;
                                                                  foreach my $i (1..10) {
                                                                                                          Trace = on
                                                                                                            DB<2> c
    –   nNext 运行一行                                          5
                                                            6
                                                                      $j += $i;
                                                                      print "$i is $i, $j is $jn";
                                                                                                          $i is 8, $j is 36
                                                                                                          main::(C:bug.pl:4):    foreach my $i
    –
                                                            7     }                                       (1..10) {
        r     Return 运行到当前子程序结束                             8     1;                                      main::(C:bug.pl:5):            $j += $i;
                                                                                                          main::(C:bug.pl:6):            print
    –   p 变量名        查看变量                                   C:>bug.pl                                    "$i is $i, $j is $jn";
                                                            Default die handler restored.                 $i is 9, $j is 45
    –   x 变量名        查看变量,友好格式(hash用引用)                                                                   main::(C:bug.pl:4):    foreach my $i
                                                            Loading DB routines from perl5db.pl           (1..10) {
    –   l/-/w 列出前后的代码                                       version 1.07
                                                            Editor support available.
                                                                                                          main::(C:bug.pl:5):
                                                                                                          main::(C:bug.pl:6):
                                                                                                                                          $j += $i;
                                                                                                                                          print
    –   c 行号         执行到"行号"                                Enter h or `h h' for help, or `perldoc
                                                                                                          "$i is $i, $j is $jn";
                                                                                                          $i is 10, $j is 55
    –   c            执行,直到遇到断点                              perldebug' for more help.                     main::(C:bug.pl:4):
                                                                                                          (1..10) {
                                                                                                                                  foreach my $i

                                                                                                          main::(C:bug.pl:8):    1;
    –   b 行号         设置断点(b 子程序名)                           main::(C:bug.pl:3):
                                                              DB<1> b 6 $i == 8
                                                                                      my $j;
                                                                                                          Debugged program terminated. Use q to
                                                              DB<2> c                                     quit or R to restart,
    –   b 行号 条件      设置条件断点                                 $i is 1, $j is 1                                use O inhibit_exit to avoid stopping
                                                            $i is 2, $j is 3                              after program termination,
    –   d 行号         去除"行号"处的断点                             $i is 3, $j is 6                                h q, h R or h O to get additional info.
                                                            $i is 4, $j is 10                               DB<2>
                                                        5                                                                                          6




              测试,使用Test模块                                                 测试,使用Devel::Coverage
#!/usr/bin/perl -w
use strict;                     C:>test.pl                      •   需要到CPAN上下载、安装
use Test;                       1..10                            •   perl -d:Coverage coverage.pl
plan tests => 10;
                                not ok 1
sub s1 {
    my $j;                      # Failed test 1 in               •   生成同名的coverage.pl.cvg
    $j += $_
        foreach (1..$_[0]);
                                C:test.pl at line 13            •   运行coverperl coverage.pl.cvg显示覆盖率
    $j;                         ok 2                                          perl -d:Coverage coverage.pl
                                                                                                                显示覆盖率
}                               ok 3                                                                            C:>coverperl coverage.pl.cvp
sub s2 {
                                ok 4                            代码                                   运行         Total of 5 instrumentation runs.
    $_[0] * ($_[0] + 1) / 2;                                    #!/usr/bin/perl -w                   1
}                               ok 5                            use strict;                          3          C:coverage.pl
ok(0, s1 0);                                                    sub ss {                             6                  10 main::ss
ok(0, s2 0);
                                ok 6                                if ($_[0] <= 0) {                10                         10     line   4
ok(1, s1 1);                    ok 7                                     print "Ignoredn";
                                                                         return;
                                                                                                     15
                                                                                                     21
                                                                                                                                0
                                                                                                                                0
                                                                                                                                       line
                                                                                                                                       line
                                                                                                                                              5
                                                                                                                                              6
ok(1, s2 1);                    ok 8                                }                                28                         10     line   8
ok(3, s1 2);                                                       print $_[0] * ($_[0] + 1) / 2;    36                         10     line   9
ok(3, s2 2);                    ok 9                                print "n";                      45                 3    line 2
ok(55, s1 10);                  ok 10                           }
                                                                foreach (1..10) {
                                                                                                     55                 11   line 11
ok(55, s2 10);                                                                                                          10   line 12
ok(5050, s1 100);                                                   ss($_);                                             1    line 14
                                                                }
ok(5050, s2 100);               C:>                            1;
1;                                                      7                                                       C:>                               8
了解速度瓶颈:Devel::DProf                                                                      基于行的--Devel::SmallProf
#!/usr/bin/perl -w
use strict;                           • 运行时增加-d:DProf                                      •   用法 perl –d:SmallProf 脚本,结果在smallprof.out中
foreach (90000..100000) {s1($_);}
foreach (90000..100000) {s2($_);}
sub s1 {                                选项,会自动生成一                                          •   显示每行、而不是每个子程序的执行时间
    my $j;
    $j += $_ foreach (1..$_[0]);        个tmon.out文件                                        •   需要预装Time::HiRes,要有配套的C编译器
                                                                                           •   一些选项开关:
}
sub s2 {
    $_[0] * ($_[0] + 1) / 2;          • 查看profile结果,运行                                         – 暂时关闭和打开profile:
}
1;                                      dprofpp                                                  • $DB::profile = 0;
                                                                                                 • 这之间的代码不会被SmallProf跟踪
               C:>perl -d:DProf profile.pl
                                                                                                 • $DB::profile = 1;
               C:>dprofpp
tmon.out       Total Elapsed Time = -0.04001 Seconds                                           – 指定要跟踪的模块名称,主程序用'main'表示,例如
该文件会很大           User+System Time = 296.9769 Seconds
               Exclusive Times                                                                   • use Data::Dumper; use TK;
               %Time ExclSec CumulS #Calls sec/call Csec/c   Name                                • %DB::package = ('main' => 1, 'Data::Dumper' => 1);
                99.9   296.9 296.91 10001    0.0297 0.0297   main::s1
                0.01   0.040 0.030 10001     0.0000 0.0000   main::s2                            • 只跟踪主程序和Data::Dumper的代码执行情况
                0.00   0.010 0.010       1   0.0100 0.0100   main::BEGIN
                0.00   0.000 -0.000      1   0.0000      -   strict::import                    – 不列出执行计数为0的行
                0.00   0.000 -0.000      1   0.0000      -   strict::bits
                                                                                                 • $DB::drop_zeros = 1;
               C:>                                                              9                                                                                             10




                                       再次查看2**100
#!/usr/bin/perl -w
$DB::profile = 0;
$DB::drop_zeros = 1;                                                                                一些建议和进一步学习
                                        和$two**100
%DB::packages = ('main' => 1);
use strict;
                                                                                           • 留意typoerror
                                                                                           • 每次遇到错误后要仔细分析
use Math::BigInt;

my $two = Math::BigInt->new('2');
my $p;                                                                                     • 学Peter Scott, Ed Wright "Perl Debugged", Addison
$DB::profile = 1;
                                         • 速度大约相差460倍                                        Wesly 2001。其中译本打印错误较多,尚可阅读
foreach (1..100) {

}
    scalar $two ** 100;
                                                                                           • 学习E.S. Peschko, etc "Perl 5 Complete",Chapter 22-
foreach (1..46000) {
    scalar 2 ** 100;                    perl -d:SmallProf bigpower.pl
                                                                                             23,机械工业出版社有中译本"Perl 5 编程祥解"
}                                       type smallprof.out
                                                                                           • 学习Perl的调试器, 看perldebtut, perldebug
1;

           ================ SmallProf version 2.00_03 ================
                                                                                           • 自己编写Perl调试器,看perldebguts帮助主页
                             Profile of bigpower.pl                     Page 1
        =================================================================                  • 编写Regression Test代码,多测试边界条件
                                                                                           • 使用Coverage和DProf,了解代码的执行情况
     count wall tm cpu time line
         1 0.000165 0.000000     2:$DB::profile = 0;
       101 0.000281 0.000000    13:foreach (1..100) {
       100 0.376569 0.370000
     46001 0.084747 0.330000
                                14:   scalar $two ** 100;
                                16:foreach (1..46000) {
                                                                                           • 学习Devel::类的模块
                                                                                                                                                                McGraw-Hill 1998
     46000 0.080029 0.360000    17:   scalar 2 ** 100;
         1 0.000017 0.000000    20:1;
                                                                                 11                                                                                            12




         其他需要知道的内容和主页                                                                      Tie::Watch实例                             • 截获变量的各种操作
                                                                                                                                    •   for all: -fetch, -store, -destroy
 •   perldiag 解释了perl的出错信息                                                            #!/usr/bin/perl -w
                                                                                      use strict;                                   •   arr: -clear, -extend, -fetchsize,
                                                                                      use Tie::Watch;
                                                                                                                                            -pop, -push, -shift, -splice,
 •   perlsytle 一些可供参考的perl编程风格                                                        my @arr;                                              -storesize, -unshift.
 •   use diagnostics; 比perl –w更详细的警告信息                                                my $watch = new Tie::Watch(                   •   hash: -clear, -delete, -exists,
                                                                                          -variable => @arr,
                                                                                                                                            -firstkey, -nextkey
 •   use Carp qw(cluck); carp/cluck/croak/confess                                         -store => &store,
                                                                                          -fetch => &fetch,
                                                                                          -destroy => sub {print "Destroy.n"},     • 详见Perl手册
      – confess打印全部调用堆栈并终止,可以替代die                                                        );
                                                                                                                                         运行结果
 • %SIG的用法,截获系统信号量和特殊的__DIE__,
                                                                                      @arr = (3, 1, 4, 16);
                                                                                      print "@arrn";
                                                                                                                                         C:>tie.pl
   __WARN__                                                                           sub store {                                        Store 3 to index 0.
                                                                                          my ($tie, $k, $v) = @_;                        Store 1 to index 1.
      – $SIG{INT} = sub { die "Ooopsn"; };                                               $tie->Store($k, $v);                           Store 4 to index 2.
                                                                                          print "Store $v to index $k.n";               Store 16 to index 3.
      – use Carp;                                                                     }                                                  Fetch index 0, value   is   3.
                                                                                                                                         Fetch index 1, value   is   1.
      – $SIG{'__DIE__'} = sub {confess "@_"; };                                       sub fetch {                                        Fetch index 2, value   is   4.
                                                                                           my ($tie, $k) = @_;                           Fetch index 3, value   is   16.
 • 记得使用Data::Dumper()和Tie::Watch()                                                         my ($v) = $tie->Fetch($k);
                                                                                          print "Fetch index $k, value is $v.n";
                                                                                                                                         3 1 4 16
                                                                                                                                         Destroy.

      – Tie::Watch():跟踪变量赋值、访问等情况,查
                                                                                           $v;
                                                                                      }                                                  C:>

         找数据错误时十分有效!                                                             13   1;                                                                                       14

More Related Content

What's hot

C語言 第一章 C語言簡介
C語言 第一章 C語言簡介C語言 第一章 C語言簡介
C語言 第一章 C語言簡介shademoon
 
系統程式 -- 第 2 章
系統程式 -- 第 2 章系統程式 -- 第 2 章
系統程式 -- 第 2 章
鍾誠 陳鍾誠
 
10 檔案說明與處理
10 檔案說明與處理10 檔案說明與處理
10 檔案說明與處理shademoon
 
系統程式 -- 第 4 章 組譯器
系統程式 -- 第 4 章 組譯器系統程式 -- 第 4 章 組譯器
系統程式 -- 第 4 章 組譯器
鍾誠 陳鍾誠
 
C語言 第4章 基本輸出與輸入功能
C語言 第4章 基本輸出與輸入功能C語言 第4章 基本輸出與輸入功能
C語言 第4章 基本輸出與輸入功能shademoon
 
系統程式 -- 第 5 章 連結與載入
系統程式 -- 第 5 章 連結與載入系統程式 -- 第 5 章 連結與載入
系統程式 -- 第 5 章 連結與載入
鍾誠 陳鍾誠
 
第三章 栈和队列(新)
第三章 栈和队列(新)第三章 栈和队列(新)
第三章 栈和队列(新)
Wang Yizhe
 
系統程式 - 附錄
系統程式 - 附錄系統程式 - 附錄
系統程式 - 附錄
鍾誠 陳鍾誠
 
Bash入门基础篇
Bash入门基础篇Bash入门基础篇
Bash入门基础篇Zhiyao Pan
 
1 C入門教學
1  C入門教學1  C入門教學
1 C入門教學Sita Liu
 
系統程式 -- 附錄
系統程式 -- 附錄系統程式 -- 附錄
系統程式 -- 附錄
鍾誠 陳鍾誠
 
系統程式 - 第二章
系統程式 - 第二章系統程式 - 第二章
系統程式 - 第二章
鍾誠 陳鍾誠
 
系統程式 -- 第 11 章 嵌入式系統
系統程式 -- 第 11 章 嵌入式系統系統程式 -- 第 11 章 嵌入式系統
系統程式 -- 第 11 章 嵌入式系統
鍾誠 陳鍾誠
 
Learning python in the motion picture industry by will zhou
Learning python in the motion picture industry   by will zhouLearning python in the motion picture industry   by will zhou
Learning python in the motion picture industry by will zhou
Will Zhou
 
系統程式 -- 第 9 章 虛擬機器
系統程式 -- 第 9 章 虛擬機器系統程式 -- 第 9 章 虛擬機器
系統程式 -- 第 9 章 虛擬機器
鍾誠 陳鍾誠
 
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
Justin Lin
 
《Java程序设计》期末考试试题 (六)
《Java程序设计》期末考试试题 (六)《Java程序设计》期末考试试题 (六)
《Java程序设计》期末考试试题 (六)
jane2006
 
OOP in C - Virtual Function (Chinese Version)
OOP in C - Virtual Function (Chinese Version)OOP in C - Virtual Function (Chinese Version)
OOP in C - Virtual Function (Chinese Version)Kai-Feng Chou
 
系統程式 -- 第 3 章 組合語言
系統程式 -- 第 3 章 組合語言系統程式 -- 第 3 章 組合語言
系統程式 -- 第 3 章 組合語言
鍾誠 陳鍾誠
 
Intro to C++ Basic
Intro to C++ BasicIntro to C++ Basic
Intro to C++ Basic
Shih Chi Lin
 

What's hot (20)

C語言 第一章 C語言簡介
C語言 第一章 C語言簡介C語言 第一章 C語言簡介
C語言 第一章 C語言簡介
 
系統程式 -- 第 2 章
系統程式 -- 第 2 章系統程式 -- 第 2 章
系統程式 -- 第 2 章
 
10 檔案說明與處理
10 檔案說明與處理10 檔案說明與處理
10 檔案說明與處理
 
系統程式 -- 第 4 章 組譯器
系統程式 -- 第 4 章 組譯器系統程式 -- 第 4 章 組譯器
系統程式 -- 第 4 章 組譯器
 
C語言 第4章 基本輸出與輸入功能
C語言 第4章 基本輸出與輸入功能C語言 第4章 基本輸出與輸入功能
C語言 第4章 基本輸出與輸入功能
 
系統程式 -- 第 5 章 連結與載入
系統程式 -- 第 5 章 連結與載入系統程式 -- 第 5 章 連結與載入
系統程式 -- 第 5 章 連結與載入
 
第三章 栈和队列(新)
第三章 栈和队列(新)第三章 栈和队列(新)
第三章 栈和队列(新)
 
系統程式 - 附錄
系統程式 - 附錄系統程式 - 附錄
系統程式 - 附錄
 
Bash入门基础篇
Bash入门基础篇Bash入门基础篇
Bash入门基础篇
 
1 C入門教學
1  C入門教學1  C入門教學
1 C入門教學
 
系統程式 -- 附錄
系統程式 -- 附錄系統程式 -- 附錄
系統程式 -- 附錄
 
系統程式 - 第二章
系統程式 - 第二章系統程式 - 第二章
系統程式 - 第二章
 
系統程式 -- 第 11 章 嵌入式系統
系統程式 -- 第 11 章 嵌入式系統系統程式 -- 第 11 章 嵌入式系統
系統程式 -- 第 11 章 嵌入式系統
 
Learning python in the motion picture industry by will zhou
Learning python in the motion picture industry   by will zhouLearning python in the motion picture industry   by will zhou
Learning python in the motion picture industry by will zhou
 
系統程式 -- 第 9 章 虛擬機器
系統程式 -- 第 9 章 虛擬機器系統程式 -- 第 9 章 虛擬機器
系統程式 -- 第 9 章 虛擬機器
 
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
 
《Java程序设计》期末考试试题 (六)
《Java程序设计》期末考试试题 (六)《Java程序设计》期末考试试题 (六)
《Java程序设计》期末考试试题 (六)
 
OOP in C - Virtual Function (Chinese Version)
OOP in C - Virtual Function (Chinese Version)OOP in C - Virtual Function (Chinese Version)
OOP in C - Virtual Function (Chinese Version)
 
系統程式 -- 第 3 章 組合語言
系統程式 -- 第 3 章 組合語言系統程式 -- 第 3 章 組合語言
系統程式 -- 第 3 章 組合語言
 
Intro to C++ Basic
Intro to C++ BasicIntro to C++ Basic
Intro to C++ Basic
 

Viewers also liked

Erasmus+ project "United We Play, United We Win" 1st learning meeting in Moli...
Erasmus+ project "United We Play, United We Win" 1st learning meeting in Moli...Erasmus+ project "United We Play, United We Win" 1st learning meeting in Moli...
Erasmus+ project "United We Play, United We Win" 1st learning meeting in Moli...
Vaida Šarkauskienė
 
Francia miguel
Francia miguelFrancia miguel
Francia miguel
XtianLillo
 
Kıyamet günü. turkish (türkçe)
Kıyamet günü. turkish (türkçe)Kıyamet günü. turkish (türkçe)
Kıyamet günü. turkish (türkçe)
HarunyahyaTurkish
 
Importancia del correcto lavado de manos b
Importancia del correcto lavado de manos bImportancia del correcto lavado de manos b
Importancia del correcto lavado de manos b
Gilberto Sabino
 
Antonio torrado 1
Antonio torrado 1Antonio torrado 1
Antonio torrado 1
laurabraga
 
Proyecto informatica
Proyecto informaticaProyecto informatica
Proyecto informatica
Elixa Viteri
 
Abcdiloveyou
AbcdiloveyouAbcdiloveyou
Abcdiloveyou
Kamilia Mirdzhafarov
 
Diapositivas del metodologias docentes
Diapositivas del metodologias docentes Diapositivas del metodologias docentes
Diapositivas del metodologias docentes
tesla cordova
 
Tohum mucizesi. turkish (türkçe)
Tohum mucizesi. turkish (türkçe)Tohum mucizesi. turkish (türkçe)
Tohum mucizesi. turkish (türkçe)
HarunyahyaTurkish
 
Ilusão de ótica em caminhões
Ilusão de ótica em caminhõesIlusão de ótica em caminhões
Ilusão de ótica em caminhões
flaviopantalena
 
Rumanía maría
Rumanía maríaRumanía maría
Rumanía maría
XtianLillo
 
Dzikir Dibaca di Waktu Pagi
Dzikir Dibaca di Waktu PagiDzikir Dibaca di Waktu Pagi
Dzikir Dibaca di Waktu PagiYohanita Tengku
 
Compuhacerrapido 130331214029-phpapp01
Compuhacerrapido 130331214029-phpapp01Compuhacerrapido 130331214029-phpapp01
Compuhacerrapido 130331214029-phpapp01
Brandon Johao
 
Sivrisinek mucizesi. turkish (türkçe)
Sivrisinek mucizesi. turkish (türkçe)Sivrisinek mucizesi. turkish (türkçe)
Sivrisinek mucizesi. turkish (türkçe)
HarunyahyaTurkish
 
Kıyamet alametleri. turkish (türkçe)
Kıyamet alametleri. turkish (türkçe)Kıyamet alametleri. turkish (türkçe)
Kıyamet alametleri. turkish (türkçe)
HarunyahyaTurkish
 

Viewers also liked (17)

Erasmus+ project "United We Play, United We Win" 1st learning meeting in Moli...
Erasmus+ project "United We Play, United We Win" 1st learning meeting in Moli...Erasmus+ project "United We Play, United We Win" 1st learning meeting in Moli...
Erasmus+ project "United We Play, United We Win" 1st learning meeting in Moli...
 
Francia miguel
Francia miguelFrancia miguel
Francia miguel
 
Presentación1
Presentación1Presentación1
Presentación1
 
Kıyamet günü. turkish (türkçe)
Kıyamet günü. turkish (türkçe)Kıyamet günü. turkish (türkçe)
Kıyamet günü. turkish (türkçe)
 
Importancia del correcto lavado de manos b
Importancia del correcto lavado de manos bImportancia del correcto lavado de manos b
Importancia del correcto lavado de manos b
 
Antonio torrado 1
Antonio torrado 1Antonio torrado 1
Antonio torrado 1
 
Proyecto informatica
Proyecto informaticaProyecto informatica
Proyecto informatica
 
Abcdiloveyou
AbcdiloveyouAbcdiloveyou
Abcdiloveyou
 
Diapositivas del metodologias docentes
Diapositivas del metodologias docentes Diapositivas del metodologias docentes
Diapositivas del metodologias docentes
 
Tohum mucizesi. turkish (türkçe)
Tohum mucizesi. turkish (türkçe)Tohum mucizesi. turkish (türkçe)
Tohum mucizesi. turkish (türkçe)
 
Ilusão de ótica em caminhões
Ilusão de ótica em caminhõesIlusão de ótica em caminhões
Ilusão de ótica em caminhões
 
Rumanía maría
Rumanía maríaRumanía maría
Rumanía maría
 
Dzikir Dibaca di Waktu Pagi
Dzikir Dibaca di Waktu PagiDzikir Dibaca di Waktu Pagi
Dzikir Dibaca di Waktu Pagi
 
Compuhacerrapido 130331214029-phpapp01
Compuhacerrapido 130331214029-phpapp01Compuhacerrapido 130331214029-phpapp01
Compuhacerrapido 130331214029-phpapp01
 
Sivrisinek mucizesi. turkish (türkçe)
Sivrisinek mucizesi. turkish (türkçe)Sivrisinek mucizesi. turkish (türkçe)
Sivrisinek mucizesi. turkish (türkçe)
 
Friend Matrix
Friend MatrixFriend Matrix
Friend Matrix
 
Kıyamet alametleri. turkish (türkçe)
Kıyamet alametleri. turkish (türkçe)Kıyamet alametleri. turkish (türkçe)
Kıyamet alametleri. turkish (türkçe)
 

Similar to Pl 06 p10.prn

Maintainable PHP Source Code
Maintainable PHP Source CodeMaintainable PHP Source Code
Maintainable PHP Source Code
Bo-Yi Wu
 
Java7 fork join framework and closures
Java7 fork join framework and closuresJava7 fork join framework and closures
Java7 fork join framework and closures
wang hongjiang
 
2, bash synax simplified
2, bash synax simplified2, bash synax simplified
2, bash synax simplified
ted-xu
 
Effective linux.1.(commandline)
Effective linux.1.(commandline)Effective linux.1.(commandline)
Effective linux.1.(commandline)
wang hongjiang
 
PHP
PHPPHP
PHP
Ht Wang
 
Shell脚本
Shell脚本Shell脚本
Shell脚本bj
 
第三章 栈和队列
第三章 栈和队列第三章 栈和队列
第三章 栈和队列
Wang Yizhe
 

Similar to Pl 06 p10.prn (7)

Maintainable PHP Source Code
Maintainable PHP Source CodeMaintainable PHP Source Code
Maintainable PHP Source Code
 
Java7 fork join framework and closures
Java7 fork join framework and closuresJava7 fork join framework and closures
Java7 fork join framework and closures
 
2, bash synax simplified
2, bash synax simplified2, bash synax simplified
2, bash synax simplified
 
Effective linux.1.(commandline)
Effective linux.1.(commandline)Effective linux.1.(commandline)
Effective linux.1.(commandline)
 
PHP
PHPPHP
PHP
 
Shell脚本
Shell脚本Shell脚本
Shell脚本
 
第三章 栈和队列
第三章 栈和队列第三章 栈和队列
第三章 栈和队列
 

Pl 06 p10.prn

  • 1. 对Perl程序员的忠告 • 区分$, @, %, 函数后的括号可以省略 • 和C语言的一些区别: Perl语言高级编程专题 – 类型的多态性 – 没有malloc/free的困扰 Lesson 10 – $a || $b不返回布尔值,返回$a或$b之一的值 – ? : 可以是左值: ($flag ? $a : $b) = 6; 周晓方 – 没有struct,union,switch等 courses@xfzhou.homeftp.org – C的i[a]和a[i]等价,perl不是 Perl调试技巧 (Peter Scott, Ed Wright, "Perl Debugged") 1 2 资源的优化 语义(理解上的差别) • 首先确保可读性和可维护性 (据Moore's law) • 语义错误:open (A, 'f) | die "Error"; • 利用任务管理器查看内存占用情况,用 • 语义错误:printf "Number of @a = %d", @a; Benchmark,Devel::DProf确定运行的时间 • 用B::Deparse查看perl对代码的理解 Deparse还很简陋,但遇到了奇怪现象,可以单独拿 • 及早结束循环:循环体开头合理增加next/last 出来试一试 • 尽量避免调用外部程序,避免` `或system( ) perl -MO=Deparse -e "for ($i=1;$i<10;$i++) {$j+=$i;}" for ($i = 1; $i < 10; ++$i) { • 节约内存:优先用数组,再hash,最后标量 $j += $i; } • 空间换速度:Memoize模块,记住已有调用 -e syntax OK • 速度换空间:大hash用tie函数关联到数据库 perl -MO=Deparse -e "use strict my $a = 1; print $a; exit;" print $a; exit; 3 -e syntax OK 4 –L 列出所有的断点 $i is 5, $j is 15 perl的调试器 –t 跟踪执行 $i is 6, $j is 21 $i is 7, $j is 28 main::(C:bug.pl:6): print • perl -d myscripts.pl 1 2 #!/usr/bin/perl -wd use strict; "$i is $i, $j is $jn"; DB<2> t – s Step 运行一行,跟踪进入子程序 3 4 my $j; foreach my $i (1..10) { Trace = on DB<2> c – nNext 运行一行 5 6 $j += $i; print "$i is $i, $j is $jn"; $i is 8, $j is 36 main::(C:bug.pl:4): foreach my $i – 7 } (1..10) { r Return 运行到当前子程序结束 8 1; main::(C:bug.pl:5): $j += $i; main::(C:bug.pl:6): print – p 变量名 查看变量 C:>bug.pl "$i is $i, $j is $jn"; Default die handler restored. $i is 9, $j is 45 – x 变量名 查看变量,友好格式(hash用引用) main::(C:bug.pl:4): foreach my $i Loading DB routines from perl5db.pl (1..10) { – l/-/w 列出前后的代码 version 1.07 Editor support available. main::(C:bug.pl:5): main::(C:bug.pl:6): $j += $i; print – c 行号 执行到"行号" Enter h or `h h' for help, or `perldoc "$i is $i, $j is $jn"; $i is 10, $j is 55 – c 执行,直到遇到断点 perldebug' for more help. main::(C:bug.pl:4): (1..10) { foreach my $i main::(C:bug.pl:8): 1; – b 行号 设置断点(b 子程序名) main::(C:bug.pl:3): DB<1> b 6 $i == 8 my $j; Debugged program terminated. Use q to DB<2> c quit or R to restart, – b 行号 条件 设置条件断点 $i is 1, $j is 1 use O inhibit_exit to avoid stopping $i is 2, $j is 3 after program termination, – d 行号 去除"行号"处的断点 $i is 3, $j is 6 h q, h R or h O to get additional info. $i is 4, $j is 10 DB<2> 5 6 测试,使用Test模块 测试,使用Devel::Coverage #!/usr/bin/perl -w use strict; C:>test.pl • 需要到CPAN上下载、安装 use Test; 1..10 • perl -d:Coverage coverage.pl plan tests => 10; not ok 1 sub s1 { my $j; # Failed test 1 in • 生成同名的coverage.pl.cvg $j += $_ foreach (1..$_[0]); C:test.pl at line 13 • 运行coverperl coverage.pl.cvg显示覆盖率 $j; ok 2 perl -d:Coverage coverage.pl 显示覆盖率 } ok 3 C:>coverperl coverage.pl.cvp sub s2 { ok 4 代码 运行 Total of 5 instrumentation runs. $_[0] * ($_[0] + 1) / 2; #!/usr/bin/perl -w 1 } ok 5 use strict; 3 C:coverage.pl ok(0, s1 0); sub ss { 6 10 main::ss ok(0, s2 0); ok 6 if ($_[0] <= 0) { 10 10 line 4 ok(1, s1 1); ok 7 print "Ignoredn"; return; 15 21 0 0 line line 5 6 ok(1, s2 1); ok 8 } 28 10 line 8 ok(3, s1 2); print $_[0] * ($_[0] + 1) / 2; 36 10 line 9 ok(3, s2 2); ok 9 print "n"; 45 3 line 2 ok(55, s1 10); ok 10 } foreach (1..10) { 55 11 line 11 ok(55, s2 10); 10 line 12 ok(5050, s1 100); ss($_); 1 line 14 } ok(5050, s2 100); C:> 1; 1; 7 C:> 8
  • 2. 了解速度瓶颈:Devel::DProf 基于行的--Devel::SmallProf #!/usr/bin/perl -w use strict; • 运行时增加-d:DProf • 用法 perl –d:SmallProf 脚本,结果在smallprof.out中 foreach (90000..100000) {s1($_);} foreach (90000..100000) {s2($_);} sub s1 { 选项,会自动生成一 • 显示每行、而不是每个子程序的执行时间 my $j; $j += $_ foreach (1..$_[0]); 个tmon.out文件 • 需要预装Time::HiRes,要有配套的C编译器 • 一些选项开关: } sub s2 { $_[0] * ($_[0] + 1) / 2; • 查看profile结果,运行 – 暂时关闭和打开profile: } 1; dprofpp • $DB::profile = 0; • 这之间的代码不会被SmallProf跟踪 C:>perl -d:DProf profile.pl • $DB::profile = 1; C:>dprofpp tmon.out Total Elapsed Time = -0.04001 Seconds – 指定要跟踪的模块名称,主程序用'main'表示,例如 该文件会很大 User+System Time = 296.9769 Seconds Exclusive Times • use Data::Dumper; use TK; %Time ExclSec CumulS #Calls sec/call Csec/c Name • %DB::package = ('main' => 1, 'Data::Dumper' => 1); 99.9 296.9 296.91 10001 0.0297 0.0297 main::s1 0.01 0.040 0.030 10001 0.0000 0.0000 main::s2 • 只跟踪主程序和Data::Dumper的代码执行情况 0.00 0.010 0.010 1 0.0100 0.0100 main::BEGIN 0.00 0.000 -0.000 1 0.0000 - strict::import – 不列出执行计数为0的行 0.00 0.000 -0.000 1 0.0000 - strict::bits • $DB::drop_zeros = 1; C:> 9 10 再次查看2**100 #!/usr/bin/perl -w $DB::profile = 0; $DB::drop_zeros = 1; 一些建议和进一步学习 和$two**100 %DB::packages = ('main' => 1); use strict; • 留意typoerror • 每次遇到错误后要仔细分析 use Math::BigInt; my $two = Math::BigInt->new('2'); my $p; • 学Peter Scott, Ed Wright "Perl Debugged", Addison $DB::profile = 1; • 速度大约相差460倍 Wesly 2001。其中译本打印错误较多,尚可阅读 foreach (1..100) { } scalar $two ** 100; • 学习E.S. Peschko, etc "Perl 5 Complete",Chapter 22- foreach (1..46000) { scalar 2 ** 100; perl -d:SmallProf bigpower.pl 23,机械工业出版社有中译本"Perl 5 编程祥解" } type smallprof.out • 学习Perl的调试器, 看perldebtut, perldebug 1; ================ SmallProf version 2.00_03 ================ • 自己编写Perl调试器,看perldebguts帮助主页 Profile of bigpower.pl Page 1 ================================================================= • 编写Regression Test代码,多测试边界条件 • 使用Coverage和DProf,了解代码的执行情况 count wall tm cpu time line 1 0.000165 0.000000 2:$DB::profile = 0; 101 0.000281 0.000000 13:foreach (1..100) { 100 0.376569 0.370000 46001 0.084747 0.330000 14: scalar $two ** 100; 16:foreach (1..46000) { • 学习Devel::类的模块 McGraw-Hill 1998 46000 0.080029 0.360000 17: scalar 2 ** 100; 1 0.000017 0.000000 20:1; 11 12 其他需要知道的内容和主页 Tie::Watch实例 • 截获变量的各种操作 • for all: -fetch, -store, -destroy • perldiag 解释了perl的出错信息 #!/usr/bin/perl -w use strict; • arr: -clear, -extend, -fetchsize, use Tie::Watch; -pop, -push, -shift, -splice, • perlsytle 一些可供参考的perl编程风格 my @arr; -storesize, -unshift. • use diagnostics; 比perl –w更详细的警告信息 my $watch = new Tie::Watch( • hash: -clear, -delete, -exists, -variable => @arr, -firstkey, -nextkey • use Carp qw(cluck); carp/cluck/croak/confess -store => &store, -fetch => &fetch, -destroy => sub {print "Destroy.n"}, • 详见Perl手册 – confess打印全部调用堆栈并终止,可以替代die ); 运行结果 • %SIG的用法,截获系统信号量和特殊的__DIE__, @arr = (3, 1, 4, 16); print "@arrn"; C:>tie.pl __WARN__ sub store { Store 3 to index 0. my ($tie, $k, $v) = @_; Store 1 to index 1. – $SIG{INT} = sub { die "Ooopsn"; }; $tie->Store($k, $v); Store 4 to index 2. print "Store $v to index $k.n"; Store 16 to index 3. – use Carp; } Fetch index 0, value is 3. Fetch index 1, value is 1. – $SIG{'__DIE__'} = sub {confess "@_"; }; sub fetch { Fetch index 2, value is 4. my ($tie, $k) = @_; Fetch index 3, value is 16. • 记得使用Data::Dumper()和Tie::Watch() my ($v) = $tie->Fetch($k); print "Fetch index $k, value is $v.n"; 3 1 4 16 Destroy. – Tie::Watch():跟踪变量赋值、访问等情况,查 $v; } C:> 找数据错误时十分有效! 13 1; 14