perl 在反引号中使用日期命令
perl with the date command in backticks
有很多脚本——实际上这家商店中所有使用日期的 Perl 脚本——都使用这种结构。它在反引号中使用日期命令。这真的很糟糕吗?它是否打开了一个子外壳或其他东西,或者只是没有 'perlish'。是否值得我遍历 SVN 中的所有脚本并将其更改为本地时间?
#!/usr/bin/perl
chomp($date=`date '+%Y%m%d'`);
if (@ARGV) {
$date = $ARGV[0] ;
}
为什么不使用 perl:
$ perl -MPOSIX -e 'print POSIX::strftime("%Y%m%d", localtime());'
20150106
?您的解决方案几乎是完美的,它需要 fork()
低级别
这是给出的 3 个解决方案的基准:代码:
#!/usr/bin/env perl
use strict; use warnings;
use Benchmark qw(:all) ;
use autodie;
open my $daveNull, ">", "/dev/null";
my $results = timethese(my $count, {
'POSIX' => sub {
use POSIX;
print $daveNull POSIX::strftime("%Y%m%d", localtime());
},
'Time::Piece' => sub {
use Time::Piece;
print $daveNull localtime()->strftime('%Y%m%d');
},
'sysdate' => sub {
chomp(my $date=`date '+%Y%m%d'`);
print $daveNull $date;
},
});
print "-----8<-------------\n";
cmpthese( $results ) ;
输出:
Benchmark: running POSIX, Time::Piece, sysdate for at least 3 CPU seconds...
POSIX: 3 wallclock secs ( 2.14 usr + 1.06 sys = 3.20 CPU) @ 234115.94/s (n=749171)
Time::Piece: 3 wallclock secs ( 2.72 usr + 0.47 sys = 3.19 CPU) @ 68128.84/s (n=217331)
sysdate: 37 wallclock secs ( 0.36 usr 2.67 sys + 20.62 cusr 8.00 csys = 31.65 CPU) @ 285.91/s (n=9049)
-----8<-------------
Rate sysdate Time::Piece POSIX
sysdate 286/s -- -100% -100%
Time::Piece 68129/s 23729% -- -71%
POSIX 234116/s 81785% 244% --
结论
POSIX
获胜。
或者您可以只使用 Time::Piece,它自 5.009005 以来一直在核心中。
use Time::Piece;
那你就可以
my $t = localtime;
print $t->strftime('%Y%m%d');
或
use Time::Piece;
print localtime()->strftime('%Y%m%d');
这使用 strftime 格式,但比加载整个 POSIX 扩展的开销要小得多。
Plus 有一堆预设格式,其中之一是 'ymd',您可以在其中指定分隔符...在这种情况下,none
print localtime()->ymd("")
查看 perldoc 以获取更多示例。
至少,仅在需要时才调用 shell:
if (@ARGV) {
$date = $ARGV[0] ;
}
else {
chomp($date=`date '+%Y%m%d'`);
}
调用 shell 只是为了丢弃结果的效率要低得多。
但是您可以通过多种方式使用纯 Perl 生成输出。 Time::Piece
模块是 Perl 核心模块,这意味着它始终存在,或者您可以使用提供它的模块之一的 strftime
。
$ perl -MTime::Piece -le '$t = new Time::Piece; print $t->ymd("");'
20150106
$ perl -MTime::Piece -le '$t = localtime; print $t->ymd("");'
20150106
$ perl -MTime::Piece -le '$t = localtime; print $t->strftime("%Y%m%d")'
20150106
$ perl -MPOSIX -le 'print strftime("%Y%m%d", localtime(time))'
20150106
$
因此,在上下文中,假设您在文件顶部添加 use Time::Piece;
,您可以这样写:
use Time::Piece;
…
if (@ARGV) {
$date = $ARGV[0] ;
}
else {
my $t = localtime;
$date = $t->ymd("");
}
除非需要,否则不会计算默认日期。
像这样调用 date
将打开一个新的 shell 环境,效率极低。用 Benchmark 试试看它有多糟糕。
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Time::Piece;
use POSIX 'strftime';
use Benchmark;
my $fmt = '%Y%m%d';
timethese(100_000, {
backticks => sub {
my $date = `date +$fmt`;
},
strftime => sub {
my $date = POSIX::strftime($fmt, localtime);
},
timepiece => sub {
my $date = localtime->strftime($fmt);
},
});
这是输出:
Benchmark: timing 100000 iterations of backticks, strftime, timepiece...
backticks: 108 wallclock secs ( 4.26 usr 25.05 sys + 4.82 cusr 85.59 csys = 119.72 CPU) @ 835.28/s (n=100000)
strftime: 1 wallclock secs ( 1.03 usr + 0.00 sys = 1.03 CPU) @ 97087.38/s (n=100000)
timepiece: 1 wallclock secs ( 1.33 usr + 0.00 sys = 1.33 CPU) @ 75187.97/s (n=100000)
反引号解决方案比其他两个选项慢大约一百倍。
但是,当然,它有效。如果您不担心程序的性能,那么请不要费心去更改它。
有很多脚本——实际上这家商店中所有使用日期的 Perl 脚本——都使用这种结构。它在反引号中使用日期命令。这真的很糟糕吗?它是否打开了一个子外壳或其他东西,或者只是没有 'perlish'。是否值得我遍历 SVN 中的所有脚本并将其更改为本地时间?
#!/usr/bin/perl
chomp($date=`date '+%Y%m%d'`);
if (@ARGV) {
$date = $ARGV[0] ;
}
为什么不使用 perl:
$ perl -MPOSIX -e 'print POSIX::strftime("%Y%m%d", localtime());'
20150106
?您的解决方案几乎是完美的,它需要 fork()
低级别
这是给出的 3 个解决方案的基准:代码:
#!/usr/bin/env perl
use strict; use warnings;
use Benchmark qw(:all) ;
use autodie;
open my $daveNull, ">", "/dev/null";
my $results = timethese(my $count, {
'POSIX' => sub {
use POSIX;
print $daveNull POSIX::strftime("%Y%m%d", localtime());
},
'Time::Piece' => sub {
use Time::Piece;
print $daveNull localtime()->strftime('%Y%m%d');
},
'sysdate' => sub {
chomp(my $date=`date '+%Y%m%d'`);
print $daveNull $date;
},
});
print "-----8<-------------\n";
cmpthese( $results ) ;
输出:
Benchmark: running POSIX, Time::Piece, sysdate for at least 3 CPU seconds...
POSIX: 3 wallclock secs ( 2.14 usr + 1.06 sys = 3.20 CPU) @ 234115.94/s (n=749171)
Time::Piece: 3 wallclock secs ( 2.72 usr + 0.47 sys = 3.19 CPU) @ 68128.84/s (n=217331)
sysdate: 37 wallclock secs ( 0.36 usr 2.67 sys + 20.62 cusr 8.00 csys = 31.65 CPU) @ 285.91/s (n=9049)
-----8<-------------
Rate sysdate Time::Piece POSIX
sysdate 286/s -- -100% -100%
Time::Piece 68129/s 23729% -- -71%
POSIX 234116/s 81785% 244% --
结论
POSIX
获胜。
或者您可以只使用 Time::Piece,它自 5.009005 以来一直在核心中。
use Time::Piece;
那你就可以
my $t = localtime;
print $t->strftime('%Y%m%d');
或
use Time::Piece;
print localtime()->strftime('%Y%m%d');
这使用 strftime 格式,但比加载整个 POSIX 扩展的开销要小得多。
Plus 有一堆预设格式,其中之一是 'ymd',您可以在其中指定分隔符...在这种情况下,none
print localtime()->ymd("")
查看 perldoc 以获取更多示例。
至少,仅在需要时才调用 shell:
if (@ARGV) {
$date = $ARGV[0] ;
}
else {
chomp($date=`date '+%Y%m%d'`);
}
调用 shell 只是为了丢弃结果的效率要低得多。
但是您可以通过多种方式使用纯 Perl 生成输出。 Time::Piece
模块是 Perl 核心模块,这意味着它始终存在,或者您可以使用提供它的模块之一的 strftime
。
$ perl -MTime::Piece -le '$t = new Time::Piece; print $t->ymd("");'
20150106
$ perl -MTime::Piece -le '$t = localtime; print $t->ymd("");'
20150106
$ perl -MTime::Piece -le '$t = localtime; print $t->strftime("%Y%m%d")'
20150106
$ perl -MPOSIX -le 'print strftime("%Y%m%d", localtime(time))'
20150106
$
因此,在上下文中,假设您在文件顶部添加 use Time::Piece;
,您可以这样写:
use Time::Piece;
…
if (@ARGV) {
$date = $ARGV[0] ;
}
else {
my $t = localtime;
$date = $t->ymd("");
}
除非需要,否则不会计算默认日期。
像这样调用 date
将打开一个新的 shell 环境,效率极低。用 Benchmark 试试看它有多糟糕。
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Time::Piece;
use POSIX 'strftime';
use Benchmark;
my $fmt = '%Y%m%d';
timethese(100_000, {
backticks => sub {
my $date = `date +$fmt`;
},
strftime => sub {
my $date = POSIX::strftime($fmt, localtime);
},
timepiece => sub {
my $date = localtime->strftime($fmt);
},
});
这是输出:
Benchmark: timing 100000 iterations of backticks, strftime, timepiece...
backticks: 108 wallclock secs ( 4.26 usr 25.05 sys + 4.82 cusr 85.59 csys = 119.72 CPU) @ 835.28/s (n=100000)
strftime: 1 wallclock secs ( 1.03 usr + 0.00 sys = 1.03 CPU) @ 97087.38/s (n=100000)
timepiece: 1 wallclock secs ( 1.33 usr + 0.00 sys = 1.33 CPU) @ 75187.97/s (n=100000)
反引号解决方案比其他两个选项慢大约一百倍。
但是,当然,它有效。如果您不担心程序的性能,那么请不要费心去更改它。