Perl性能优化的三大技巧

开发 后端
你对Perl性能优化的概念是否熟悉,Perl是强大的语言,是强大的工具,也是一道非常有味道的菜:-)利用很多perl的特性,可以实现一些非常有趣而实用的功能。

本文和大家重点讨论一下Perl性能优化技巧,利用Perl开发一些服务应用时,有时会遇到Perl性能或资源占用的问题,可以巧用require装载模块,使用系统函数及XS化模块,自写低开销模块等来优化Perl性能。

Perl性能优化

Perl是强大的语言,是强大的工具,也是一道非常有味道的菜:-)利用很多perl的特性,可以实现一些非常有趣而实用的功能。

利用Perl开发一些服务应用时,有时会遇到Perl性能或资源占用的问题,如何解决呢?以下是自己过去开发实践的一些经验,几个主要的技巧分别是:

◆巧用require装载模块
◆使用系统函数及XS化模块
◆自写低开销模块
◆优化正则表达式
◆善用BSDsocket

巧用require装载模块

为避免程序一启动就加载大量模块,降低启动速度,可以在必要的时候再装载模块,这时候就是require大派用场的时候了。
如:

  1. #!/usr/bin/perl-w  
  2. usepre_load_module;  
  3.  
  4. #Initializesomething  
  5. init_args();  
  6.  
  7. #if$use_this_moduleistrue,loadtheModule  
  8. if($use_this_module){  
  9. requireModule;  
  10. }  
  11.  

 上述代码中,如果变量$use_this_module设置了,那么才加载Module,如果没设置则不需要加载,实现了:useondemand的功能。在CGI应用程序中,这相当有用,如果每次请求(fork)都加载大量无用模块的话,响应速度会有所降低,而在特定场合才加载一些模块将加块启动、解析的速度,提高Perl性能。

再看一个例子:

  1. #!/usr/bin/perl  
  2. my$pid=forkordie"can'tfork:$!\n";  
  3. if($pid){  
  4. print"i'mfather\n";  
  5. sleep;  
  6. }else{  
  7. print"i'mchild\n":  
  8. requireIO::Socket;  
  9. sleep;  
  10. }  

上述代码中,如果在程序一开始就用use来载入IO::Socket模块,那么子/父进程都加载了该模块,通过top命令发现子父进程大小都是3.07MB;如果只在子进程里加载,则只在子进程里有效,内存的消耗将降低,top命令发现子进程3.04MB,父进程变为1.4MB。

使用系统函数及XS化模块

Perl内建的系统函数及用c编写的perlXS扩展模块的速度和效率都比纯perl的实现要好得多。在Perl性能要求较高的场合(如开发ApplicationServer,NetworkServer等),可以考虑使用这些内建函数或XS化模块。

如Socket就比IO::Socket的内存消耗要低,XS编写的Data::Dumper就比纯Perl的Data::Dumper要快4-5倍。
此外,一些简单的任务并没必要使用Perl模块,如获得主机IP地址就大可不必载入庞大的Net::DNS而只是使用gethostbyname()系统函数即可。

以下是一些常用的替代方案以获得更快的速度,更好的效率:

◆用sys*系列函数等替代open/seek/tell/<>等标准IO操作
◆用Socket代替IO::Socket以获得更低开销和内存占用
◆用get*by*系列函数代替Net::DNS
◆用index/substr等代替部分低效正则表达式
◆用select(3参数版本)代替IO::Handle部分功能.......

自写低开销模块

通常我们使用一些Perl模块时,只使用了其中很小一部分的功能,可是却不得不载入整个模块,甚至要载入其他不相关的模块。因此往往使整个程序非常臃肿庞大。
著名的web管理软件webmin的miniserv(一个简化的http服务端)功能强大,还支持SSL,但资源占用却出奇的少,只有大约5.6MB的大小!这是为什么呢?因为miniserver只使用了2个Perl系统模块(Socket及POSIX),没有载入其他的模块。一些本需要其他perl模块的功能,均由web-lib.pl等用系统函数编写代替。

例如以下是一个获得A记录的高速函数get_mx(),它不依赖任何模块,速度非常快,可以提高Perl性能。

  1. subget_mx{  
  2. my@info=gethostbynameshift;  
  3. my@addr=splice(@info,4);  
  4. my@rt;  
  5. foreach(@addr){  
  6. push@rt,join('.',unpack('C4',$_));  
  7. }  
  8. \@rt;  

另一个例子,对于标准的IO::Handle对象,可以使用$obj->autoflush(1);来设置缓冲的特性,我们通过使用系统函数select()来获得同样的能力,而无需要载入IO::Handle,代码如下:
 

  1. subautoflush{  
  2. my$io=$_[0];  
  3. select((select($io),$|=1)[0]);  

使用方法很简单,例如要对IO::Socket::INET类型的$sock设置为立即冲刷,则autoflush($sock)即可。

【编辑推荐】

  1. 从细节处提升Perl性能
  2. 三大技巧实现Perl性能优化
  3. 实例解析Perl多进程技术的应用
  4. 学习笔记 Perl split函数用法指导
  5. Perl多进程及其和多线程的关系解析

 


 

责任编辑:佚名 来源: chinaunix.net
相关推荐

2010-07-26 12:50:45

Perl性能

2011-06-14 10:35:15

性能优化

2019-08-21 10:53:29

.NET性能优化

2014-10-28 16:11:37

AndroidApp性能优化

2009-06-16 16:39:49

Hibernate性能

2010-07-13 09:23:00

Perl变量

2011-07-11 15:26:49

性能优化算法

2013-06-08 14:19:05

性能优化KVM

2010-07-20 10:48:56

Perl文件操作

2009-11-27 13:24:20

PHP代码性能优化

2022-10-09 13:36:44

接口性能优化

2012-07-23 10:22:15

Python性能优化优化技巧

2019-02-25 07:07:38

技巧React 优化

2009-12-09 17:33:22

PHP性能优化

2024-01-22 13:16:00

接口性能优化本地缓存

2010-07-20 15:54:40

Perl简单变量

2011-06-14 14:17:23

性能优化系统层次

2011-06-14 14:32:46

性能优化

2011-06-14 11:14:10

性能优化代码

2009-04-16 16:57:58

DotNetNuke优化网站开发
点赞
收藏

51CTO技术栈公众号