perl - 两阶段条件编译

问题描述 投票:1回答:2

我有相当频繁执行的非常大的perl脚本(来自cron)。 大多数执行需要非常简短的测试。

如何根据“第1部分”决定将单个文件脚本分成两部分和“第二部分”?


考虑的解决方案:

  1. 使用BEGIN{ …; exit if …; }块进行琐碎的测试。
  2. 使用require编译和执行file_2的file_1的两个文件解决方案。 如果成本合理,我更喜欢单文件解决方案来简化维护。
perl
2个回答
2
投票

首先,您应该测量编译实际需要多长时间,以确定是否需要这种“优化”。如果确实如此,那么既然你说你更喜欢单文件解决方案,那么一个可能的解决方案是使用__DATA__部分代码如下:

use warnings;
use strict;

# measure compliation and execution time
use Time::HiRes qw/ gettimeofday tv_interval /;
my $start;
BEGIN { $start = [gettimeofday] }
INIT  { printf "%.06f\n", tv_interval($start) }
END   { printf "%.06f\n", tv_interval($start) }

my $condition = 1; # dummy for testing
# conditionally compile and run the code in the DATA section
if ($condition) {
    eval do { local $/; <DATA>.'; 1' } or die $@;
}

__DATA__
# ... lots of code here ...

0
投票

我看到了实现你想要的两种方式。简单的方法是将脚本分为两部分。第一部分将进行简单的测试。然后,如果您需要进行更复杂的测试,您可以“添加”第二部分。这样做的方法是像这样使用eval

<first-script.pl>
...
eval `cat second-script.pl`;
if( $@ ) {
  print STDERR $@, "\n";
  die "Errors in the second script.\n";
}

或者以更健壮的方式使用File::Slurp

eval read_file("second-script.pl", binmode => ':utf8');

或者关注@amon建议和do

do "second-script.pl";

只要注意doeval不同:

它的不同之处还在于使用do FILE评估的代码无法在封闭范围内看到词法; eval STRING可以。然而,它是相同的,因为它每次调用它时都会重新解析文件,因此您可能不希望在循环内执行此操作。

eval将在第一个脚本的上下文中执行,因此该代码可以使用任何变量或初始化。

与此相关,有一个问题:Best way to add dynamic code to a perl application,我前段时间问过(并在所提供的评论和一些研究的帮助下回答了我自己。)我花了一些时间来记录我能为任何人(和我自己)想到的一切。参考。

我看到的第二种方法是将测试脚本变成一个守护进程,并让crontab位根据需要调用该守护进程。守护进程保持活动状态,因此您可能需要的任何数据结构都将保留在内存中。在不利方面,这将以连续的方式获取资源,因为守护进程将始终运行。

© www.soinside.com 2019 - 2024. All rights reserved.