You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用二进制、变量查找与foreach优化Perl星期转整数脚本

Perl星期缩写转位掩码脚本优化

需求描述

接收「Mon」「Tue」「Wed、Thu、Sun」这类星期缩写输入,返回对应的整数(位掩码)表示选中的星期组合。

原始实现代码

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;
}

核心优化点

  • 查找表改用普通哈希存储,减少哈希引用的一层解引用开销
  • 查找表通过map动态生成,避免手动赋值写错位值,后续调整星期顺序也更易维护
  • 使用位异或(^=)替代加法计算位掩码,更符合位操作的场景特性,就算输入重复星期也不会出错
  • 直接传入数组引用作为参数,避免数组整体拷贝的性能损耗
  • 去掉冗余的范围判断,7位的位掩码最大值就是127,不可能超过128

优化后代码与基准测试

测试对比代码

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;
}

测试结果

家用HP裸金属设备测试输出

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

Linode节点测试输出

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

性能结论

优化版本在家用设备上性能提升70%,Linode节点上性能提升34%,基准测试结果会受硬件差异影响,但优化效果显著。


内容的提问来源于stack exchange,提问作者Mark Arnold

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 08:00:04