【问题标题】:How expensive is: require "foo.pl";有多贵:需要“foo.pl”;
【发布时间】:2011-07-20 12:14:27
【问题描述】:

我将重写我过去 10 年在学习 perl 时开发的项目的大部分内容。可以进行很多优化。

代码的关键部分是一个大的 if/elsif 块,它需要 xxx.cgi 文件,具体取决于 POST 值。例如:

    if($FORM{'action'} eq "1"){require "1.cgi";}
elsif($FORM{'action'} eq "2"){require "2.cgi";}
elsif($FORM{'action'} eq "3"){require "3.cgi";}
elsif($FORM{'action'} eq "4"){require "4.cgi";}

它有更多的烦恼,但在 perl 中使用“require”有多昂贵?

【问题讨论】:

    标签: perl require


    【解决方案1】:

    require 本身在任何情况下都具有相对较低的成本,如果您在程序的一次运行中多次require 同一个文件,它将检测到该文件已经加载并且不会尝试再次加载它。但是,如果您有一个长且人口众多的搜索路径 (@INC) 并且您 require(或 use)有很多文件,则所有目录搜索可能会加起来;这并不常见(在您的情况下听起来不太可能),但可以通过重新组织您的模块目录来改进它,以便您正在加载的内容更早地显示在 @INC 中。

    前面的答案提到的潜在的主要性能损失是编译您require 文件中的代码的成本。通过将代码移动到主程序中来摆脱require不会对此有所帮助,因为仍然需要编译代码。在您的情况下,这可能会使事情变得更糟,因为它会导致所有选项的代码都在每个选项上编译,而不是仅编译用户选择的一个操作使用的代码。

    【讨论】:

    • 啊,你提到了我担心的问题。我最初担心的是,无论使用情况如何,所有需求都被编译了。如果 require 本身并不昂贵,并且只编译该程序运行所需的部分,我想我可以坚持我当前的逻辑并在其他地方进行优化。参考搜索@NIC数组;我正在调用网络应用程序的其他部分,而不是模块。使用完整路径而不是相对路径会更好吗,因为我相信如果传递了完整路径,那么 require 将不会搜索整个 @NIC 目录?
    • 由于require 不会执行脚本两次,这就是为什么dorequire 更合适的原因。 require 加载模块。 do 执行脚本。
    【解决方案2】:

    如前所述,这实际上取决于这些文件中的实际代码。最好的办法是使用Devel::NYTProf 和/或Benchmark 进行测试,看看如果您对代码的性能不满意,您的代码中花费的时间最多。

    您也可以阅读Profiling Perl on perl.com,但它使用Devel::DProf 有点过时。

    【讨论】:

    • 基准测试是我最终需要做的。话虽如此,如果上面的网关代码效率很低,那么我将不得不完全采取新的方向。其中一些是在我知道哈希是什么之前写的;)感谢您的链接,应该让我开始。
    【解决方案3】:

    没有回答您的主要问题,但我最近在Ovid blog 中阅读的代码重构仍然是一个好主意。

    【讨论】:

    • 我很清楚我可以把它放在哪里!谢谢。它不适用于上述内容,因为我在示例中过度简化了其他内容。
    【解决方案4】:

    第一次,可能很贵; Perl 必须搜索路径才能找到文件并加载它。随后的时间,它很便宜 - 查询一个表并且第二次实际上没有加载该文件。如果这是在每个请求运行一次然后退出的 CGI 中,那么这不太好。

    【讨论】:

      【解决方案5】:

      这实际上取决于您调用的文件的大小。如果您有大量 CGI 文件,那么它可能会损害您的软件的性能。如果我们每人谈论 6 或 7 行代码,那么没问题。尝试在有无的情况下对程序的性能进行基准测试,并做出自己的判断。

      【讨论】:

        猜你喜欢
        • 2010-12-05
        • 1970-01-01
        • 1970-01-01
        • 2012-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-08
        • 1970-01-01
        相关资源
        最近更新 更多