簡體   English   中英

在反引號中使用date命令的perl

[英]perl with the date command in backticks

有一堆腳本 - 實際上這個商店中使用日期的所有Perl腳本 - 都使用這種結構。 它在反引號中使用date命令。 這真的很糟糕嗎? 它是打開子殼還是其他東西,或者只是不是'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

你的解決方案只是perlish而且需要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以來一直在Core中。

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',您可以在其中指定分隔符...在這種情況下,沒有

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)

反引號解決方案比其他兩個選項慢約一百倍。

但是,當然,它有效。 如果你不擔心程序的性能,那么就不用費心去改變它了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM