gpt4 book ai didi

perl - Perl 中字符串的最快校验位例程是什么?

转载 作者:行者123 更新时间:2023-12-01 08:38:59 24 4
gpt4 key购买 nike

给定一串数字,我必须使用 Perl 尽快对所有数字求和。

我的第一个实现是用 unpack() 解包数字,然后用 List::Utils 的 sum() 对数字列表求和。它非常快,但是否有更快的打包/解包方法来完成这项任务?

我尝试了打包/解包组合,并对这两种实现进行了基准测试。使用的 CPU 时间几乎相同;也许有一些我不知道的快速技巧?

这是我做基准测试的方法:

#!/usr/bin/env perl

use 5.012;
use strict;
use List::Util qw/sum/;
use Benchmark qw/timethese/;

timethese ( 1000000, {
list_util => sub {
my $CheckDigit = "999989989";
do {
$CheckDigit = sum( unpack( 'AAAAAAAAA', $CheckDigit ) );
} while ( $CheckDigit > 9 );
},
perl_only => sub {
my $CheckDigit = "999989989";
do {
$CheckDigit = unpack( '%16S*', pack( 'S9', unpack( 'AAAAAAAAA', $CheckDigit ) ) );
} while ( $CheckDigit > 9 );
},
} );

最佳答案

unpack 不是拆分字符串的最快方法:

#!/usr/bin/env perl

use strict;
use List::Util qw/sum/;
use Benchmark qw/cmpthese/;

cmpthese ( -3, {
list_util => sub {
my $CheckDigit = "999989989";
do {
$CheckDigit = sum( unpack( 'AAAAAAAAA', $CheckDigit ) );
} while ( $CheckDigit > 9 );
},
unpack_star => sub {
my $CheckDigit = "999989989";
do {
$CheckDigit = sum( unpack( '(A)*', $CheckDigit ) );
} while ( $CheckDigit > 9 );
},
re => sub {
my $CheckDigit = "999989989";
do {
$CheckDigit = sum( $CheckDigit =~ /(.)/g );
} while ( $CheckDigit > 9 );
},
split => sub {
my $CheckDigit = "999989989";
do {
$CheckDigit = sum( split //, $CheckDigit );
} while ( $CheckDigit > 9 );
},
perl_only => sub {
my $CheckDigit = "999989989";
do {
$CheckDigit = unpack( '%16S*', pack( 'S9', unpack( 'AAAAAAAAA', $CheckDigit ) ) );
} while ( $CheckDigit > 9 );
},
modulo => sub {
my $CheckDigit = "999989989";
$CheckDigit = ($CheckDigit+0) && ($CheckDigit % 9 || 9);
},
} );

生产:

                 Rate perl_only list_util       re unpack_star    split   modulo
perl_only 89882/s -- -15% -30% -45% -54% -97%
list_util 105601/s 17% -- -17% -35% -45% -97%
re 127656/s 42% 21% -- -21% -34% -96%
unpack_star 162308/s 81% 54% 27% -- -16% -95%
split 193405/s 115% 83% 52% 19% -- -94%
modulo 3055254/s 3299% 2793% 2293% 1782% 1480% --

因此,如果您必须将字符串拆分为字符,那么 split 看起来是您的最佳选择。

但反复将数字相加是almost the same as taking the number mod 9 (正如米罗德指出的那样)。不同之处在于 $Digits % 9 产生 0 而不是 9。一个可以解决此问题的公式是 ($Digits-1) % 9 + 1,但是(在 Perl 中至少)这不适用于全零情况(它产生 9 而不是 0)。在 Perl 中有效的表达式是 ($Digits+0) && ($Digits % 9 || 9)。第一项处理全零情况,第二项处理正常情况,第三项处理 0 到 9。

关于perl - Perl 中字符串的最快校验位例程是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6355531/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com