Tại sao lại ở đây sub
eins
với số else
chậm hơn sub
zwei
với số elsif
?Có chậm hơn elsif không?
#!/usr/bin/env perl
use warnings;
use 5.012;
use Benchmark qw(:all);
my $d = 0;
my $c = 2;
sub eins {
if ($c == 1) {
$d = 1;
}
else {
$d = 2;
}
}
sub zwei {
if ($c == 1) {
$d = 1;
}
elsif ($c == 2) {
$d = 2;
}
}
sub drei {
$d = 1;
$d = 2 if $c == 2;
}
cmpthese(-5, {
eins => sub{ eins() },
zwei => sub{ zwei() },
drei => sub{ drei() },
});
Rate eins drei zwei
eins 4167007/s -- -1% -16%
drei 4207631/s 1% -- -15%
zwei 4972740/s 19% 18% --
Rate eins drei zwei
eins 4074356/s -- -8% -16%
drei 4428649/s 9% -- -9%
zwei 4854964/s 19% 10% --
Rate eins drei zwei
eins 3455697/s -- -6% -19%
drei 3672628/s 6% -- -14%
zwei 4250826/s 23% 16% --
Rate eins drei zwei
eins 2832634/s -- -8% -19%
drei 3088931/s 9% -- -12%
zwei 3503197/s 24% 13% --
Rate eins zwei drei
eins 3053821/s -- -17% -26%
zwei 3701601/s 21% -- -10%
drei 4131128/s 35% 12% --
Rate eins drei zwei
eins 3033041/s -- -2% -12%
drei 3092511/s 2% -- -10%
zwei 3430837/s 13% 11% --
Summary of my perl5 (revision 5 version 16 subversion 0) configuration:
Platform:
osname=linux, osvers=3.1.10-1.9-desktop, archname=x86_64-linux
uname='linux linux1 3.1.10-1.9-desktop #1 smp preempt thu apr 5 18:48:38 utc 2012 (4a97ec8) x86_64 x86_64 x86_64 gnulinux '
config_args='-de'
hint=recommended, useposix=true, d_sigaction=define
useithreads=undef, usemultiplicity=undef
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
use64bitint=define, use64bitall=define, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O2',
cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
ccversion='', gccversion='4.6.2', gccosandvers=''
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
libpth=/usr/local/lib /lib/../lib64 /usr/lib/../lib64 /lib /usr/lib /lib64 /usr/lib64 /usr/local/lib64
libs=-lnsl -lndbm -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
libc=/lib/libc-2.14.1.so, so=so, useshrplib=false, libperl=libperl.a
gnulibc_version='2.14.1'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector'
Characteristics of this binary (from libperl):
Compile-time options: HAS_TIMES PERLIO_LAYERS PERL_DONT_CREATE_GVSV
PERL_MALLOC_WRAP PERL_PRESERVE_IVUV USE_64_BIT_ALL
USE_64_BIT_INT USE_LARGE_FILES USE_LOCALE
USE_LOCALE_COLLATE USE_LOCALE_CTYPE
USE_LOCALE_NUMERIC USE_PERLIO USE_PERL_ATOF
Built under linux
Compiled at May 24 2012 20:53:15
%ENV:
PERL_HTML_DISPLAY_COMMAND="/usr/bin/firefox -new-window %s"
@INC:
/usr/local/lib/perl5/site_perl/5.16.0/x86_64-linux
/usr/local/lib/perl5/site_perl/5.16.0
/usr/local/lib/perl5/5.16.0/x86_64-linux
/usr/local/lib/perl5/5.16.0
.
Tôi đặt đây là nhận xét bởi vì tôi không biết chắc chắn cách thức hoạt động của perl, nhưng tôi đoán rằng cấu trúc 'elsif' của' zwei' có thể tìm thấy nhanh hơn vì nó được gắn một cách rõ ràng thành '$ c' là' 2' và '$ c' luôn là' 2'. Nếu thông dịch viên đủ thông minh để tìm ra rằng '$ c' không bao giờ thay đổi, điều đó có thể giải thích được. Nếu không có điều đó mặc dù bạn sẽ mong đợi 'zwei' là chậm hơn, vì nó chắc chắn sẽ phải kiểm tra' $ c' hai lần. –
Trình thông dịch cũng có thể biến điều kiện 'zwei' thành một bảng nhảy như C thực hiện với' chuyển'. – msw
@Matthew Walton, '$ c' có thể thay đổi đơn giản bằng cách tìm nạp nó, do đó, thông dịch viên
không thể và không thực hiện bất kỳ tối ưu hóa nào như vậy. – ikegami