简体   繁体   English

优化Perl脚本

[英]Optimization Perl script


Is it possible to make this script faster ? 是否可以使此脚本更快?

#!/usr/bin/perl -w
    use strict;
    use CGI;
    package SwitchGUI;

    sub new {
        my ($classe, $nom, $nbports, $gio) = @_;

        my $this = {
            "nom"     => $nom,
            "nbports" => $nbports,
            "gio"     => $gio
        };

        bless($this, $classe);
        $this->afficher();
        return $this;   
    }

    sub afficher {
        my ($this) = @_;
        my @tab = ( 1 .. $this->{nbports} );
        my @odd = grep { $_ % 2 } @tab;
        my @even = grep { not $_ % 2 } @tab;

        my $cgi = new CGI;
        my $i;
        my $j;

        print "<div id=\"$this->{nom}\" class=\"switch\">\n";
        print $cgi->h2("$this->{nom}");

        print "<div class=\"ports\">";
        for my $port (@odd) {
            my $res = `perl ifname-index.pl -h $this->{nom} -i FastEthernet0/$port -c reseau`;

            if ($res =~ /^Erreur /) {
                print $cgi->img({
                src => 'ressources/interface_haut_down.png',  
                alt => "port n°$port",
                }), "\n",
            }
            else {
                print $cgi->a({class=>"tooltip", title=>$res},$cgi->img({
                src => 'ressources/interface_haut_up.png',  
                alt => "port n°$port",
                }), "\n",)
            }
        }

        print "<br/>";
        for my $port (@even) {
            my $res = `perl ifname-index.pl -h $this->{nom} -i FastEthernet0/$port -c reseau`;      
            if ($res =~ /^Erreur/) {
                print $cgi->img({
                src => 'ressources/interface_bas_down.png',  
                alt => "port n°$port",
                }), "\n",
            }
            else {
                if ($this->getDuplex($res)!="Full") {
                    print $cgi->a({class=>"tooltip", title=>$res},$cgi->img({
                    src => 'ressources/interface_bas_duplex.png',  
                    alt => "port n°$port",
                    }), "\n",)
                }
                elsif ($this->getVitesse($res)!="100"){
                    print $cgi->a({class=>"tooltip", title=>$res},$cgi->img({
                    src => 'ressources/interface_bas_speed.png',  
                    alt => "port n°$port",
                    }), "\n",)
                }
                else {
                    print $cgi->a({class=>"tooltip", title=>$res},$cgi->img({
                    src => 'ressources/interface_bas_up.png',  
                    alt => "port n°$port",
                    }), "\n",)
                }
            }
        }
        print "</div>";
        print "<div class=\"gio\">";
        for ($j=0;$j<$this->{gio};$j++) {
            my $req = system("perl ifname-index.pl -h $this->{nom} -i GigabitEthernet0/$j -c reseau &");
            print $cgi->img({
                src => 'ressources/interface_bas_down.png',  
                alt => "port",
                });
        }
        print "</div>\n";

        print "</div>\n";

    }

    1;

It executes a perl script (which uses SNMP to query network equipment), and depending of the return of this script, it displays an appropriate image and description. 它执行一个perl脚本(使用SNMP查询网络设备),并根据此脚本的返回,显示适当的图像和描述。 This script is used for ajax call, from another cgi script. 该脚本用于另一个cgi脚本的ajax调用。

My question is: can I execute multiple script by adding & or something similar 我的问题是: 我可以通过添加&或类似的东西来执行多个脚本吗?
at the end of the following line? 在下一行的末尾?

my $res = `perl ifname-index.pl -h $this->{nom} -i FastEthernet0/$port -c reseau`;

While i don't want comment much things like using CGI and "print" (in 2011 is really archaic), I will comment two lines: 尽管我不想评论使用CGI和“ print”之类的东西(在2011年确实是过时的),但我将评论两行:

my $res = `perl ifname-index.pl -h $this->{nom} -i FastEthernet0/$port -c reseau`;
...
my $req = system("perl ifname-index.pl -h $this->{nom} -i GigabitEthernet0/$j -c reseau &");

Starting another perl-processes really slowing speed down. 启动另一个perl进程确实会降低速度。
You're making package for displaying HTML, but not for polling? 您正在制作用于显示HTML的程序包,但不用于轮询吗?

Re-factor ifname-index.pl to subroutine. ifname-index.pl为子例程。 So, 所以,

my $res = get_request_interface(name => $this->{nom}, interface => "FastEthernet0/$port");

or to an package (the right way) - something like... 或包装(正确的方式)-类似于...

my $interface = My::Interface::Handler->new();
my $res = $interface->get_request;
...
my $another_result = $interface->get_request;
#etc

And ofc, it is possible start more (multiple) processes and communicate with them, but the solution will be probably more complicated than refactoring ifname-index.pl to subroutine. 而且, 可以启动更多(多个)进程并与之通信,但是与将ifname-index.pl重构为子例程相比,该解决方案可能更复杂。 (read this: http://faq.perl.org/perlfaq8.html#How_do_I_start_a_pro ) (阅读: http : //faq.perl.org/perlfaq8.html#How_do_I_start_a_pro

Summarization for a "cool" app - based on comments: 总结“酷”应用程序-基于评论:

  • build a web page where you list the interfaces, for example N-status lines for N ports 建立一个网页,在其中列出接口,例如N个端口的N状态行
  • the page will send N ajax (parallel) requests to the server for the status with javascript 该页面将使用javascript将N ajax(并行)请求发送到服务器以获取状态
  • the server will execute N parallel SNMP requests, and send N ajax responses 服务器将执行N个并行SNMP请求,并发送N个ajax响应
  • the page will get responses from the server and update the correct divs 该页面将获得服务器的响应并更新正确的div

With above way: 用上面的方法:

  • the user get immediately an web page 用户立即获得一个网页
  • the page has a feedback for user - "wait, i'm working on getting status" 该页面为用户提供了反馈-“等等,我正在努力获取状态”
  • the server executing N parallel requests to snmp 服务器执行对Snmp的N个并行请求
  • ajax responses updating the page as they come from the server ajax响应更新页面,因为它们来自服务器

For the web part is the best to use PGSI-type server. 对于Web部件,最好使用PGSI型服务器。 Check CPAN, several one exists. 检查CPAN,存在多个。 Tatsuhiko Miyagawa is "The Perl Hero" for these days :) Tatsuhiko Miyagawa Tatsuhiko Miyagawa 已是 “ Perl英雄” :)

Ps: 附:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM