gpt4 book ai didi

arrays - 如何使用二进制、变量查找和 foreach 优化代码?

转载 作者:行者123 更新时间:2023-12-05 08:36:30 25 4
gpt4 key购买 nike

如何优化这个 Perl 脚本?

它接受“星期几”,例如“星期一”和“星期二”或“星期三、星期四和星期日”,并简单地返回一个整数来表示它们。

use strict;
use feature qw(signatures);
use warnings;
no warnings qw(experimental::signatures);
my $DAYS_OF_WEEK_LOOKUP = ( { mon => 1, tue => 2, wed => 4, thu => 8, fri => 16, sat => 32, sun => 64 });

my $days_of_week_integer= days_of_week_to_int (['zzz', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'fri', 'SAT']);
print "$days_of_week_integer\n";


sub days_of_week_to_int ($days) {
my $day_of_week = 0;
foreach my $key (@$days) {
$day_of_week += $DAYS_OF_WEEK_LOOKUP->{lc($key)} if $DAYS_OF_WEEK_LOOKUP->{lc($key)};
}
return $day_of_week if $day_of_week < 128;
return;
}

我一直在寻求了解如何更好地优化我的代码并从经验丰富的开发人员那里获得经验。该脚本运行得非常好,而且它是在 Perl 中运行的,所以它已经运行得非常快。

但是,我不禁觉得有一种更优化的“Perl 方式”可以达到相同的结果,我想知道是否有人有同样的感觉并可以向我展示这种方式。小技巧就是重要技巧!

谢谢大家,我在这里添加了带有基准测试的最终代码。这是我的原始代码,去除了额外的开销,但忠实于带有北极熊代码的原始代码。

use strict;
use Benchmark ':all';

my $polar_bitmap = 0x01;
my @polar_days_of_week = qw/Mon Tue Wed Thu Fri Sat Sun/; # USA/Canada week days order
my $orig_DAYS_OF_WEEK_LOOKUP = ( { Mon => 1, Tue => 2, Wed => 4, Thu => 8, Fri => 16, Sat => 32, Sun => 64 });
my %polar_DAYS_OF_WEEK_LOOKUP = map { $_ => ( $polar_bitmap <<= 1 ) / 2 } @polar_days_of_week;

my @days;
@days = qw/Mon Wed Tue Sat Sun Thu/;

print "orig : " . (orig_days_of_week_to_int(@days)) . "\n";
print "polar : " . (polar_days_to_mask ( \@days)) . "\n";

@days = qw/Mon Sat Sun Thu/;

print "polar : " . (polar_days_to_mask(\@days)) . "\n";
print "orig : " . (orig_days_of_week_to_int(@days)) . "\n";

@days = qw/Mon Wed Tue Sat Sun Thu/;

cmpthese(-3, {
orginal => sub { orig_days_of_week_to_int(@days) },
polar_b => sub { polar_days_to_mask(\@days) },
});

exit 0;

sub polar_days_to_mask {
my $days = shift;
my $mask;

$mask ^= $polar_DAYS_OF_WEEK_LOOKUP{$_} for @$days;

return $mask;
}

sub orig_days_of_week_to_int {
my @days = @_;
my $day_of_week = 0;
foreach my $key (@days) {
$day_of_week += $orig_DAYS_OF_WEEK_LOOKUP->{$key};
}
return $day_of_week;
}

输出:

orig  : 111
polar : 111
polar : 105
orig : 105
Rate orginal polar_b
orginal 1411082/s -- -41%
polar_b 2398719/s 70% --

我已经添加了上面的代码,以防万一我搞砸了任何事情,因为您应该始终小心使用 BenchMarks! :-)

为了证明以上观点...我想我会用我拥有的 LINODE 节点对其进行测试...

            Rate orginal polar_b
orginal 741061/s -- -25%
polar_b 992490/s 34% --

实际上,与我在家使用的 HP 裸机相比...LINODE 始终如一地为我提供 34% 的性能,而我的家用机器为 70%。 (相同的操作系统,相同的版本)

所以你是...警惕基准!

尽管如此,Polar 解决方案既是人,又是熊,又是 AI,还是很酷的。

最佳答案

我没有做过任何基准测试,但我认为这更干净(评论中的注释):

#!/usr/bin/env perl
use strict;
use warnings;
use experimental qw/signatures/; # Instead of use feature and no warnings
use feature qw/say/;
use List::Util qw/sum0/;

# Plain hash instead of hashref
my %DAYS_OF_WEEK_LOOKUP = ( mon => 1, tue => 2, wed => 4, thu => 8,
fri => 16, sat => 32, sun => 64 );

# Function takes a list of values instead of a single arrayref
my $days_of_week_integer = days_of_week_to_int('zzz', 'Sun', 'Mon',
'Tue', 'Wed', 'Thu', 'fri', 'SAT');

# say instead of "print "$foo\n"
say $days_of_week_integer;

sub days_of_week_to_int (@days) {
no warnings qw/uninitialized/; # Turn off warning about undef values
# Sum up the results of a hash slice instead of using an explicit loop
my $day_of_week = sum0 @DAYS_OF_WEEK_LOOKUP{map { lc } @days};
return $day_of_week < 128 ? $day_of_week : undef;
}

关于arrays - 如何使用二进制、变量查找和 foreach 优化代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68823888/

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