Perl:分配[]或{}是否昂贵?如何快速重置数字/关联数组?

问题描述

| 我有一个纸牌游戏-用Perl编写,几乎没有对象,就像这样:
package PlayingTable;

our (%Games,$Num);

sub new {
        my $pkg   = shift;

        my $game = {
                ID        => ++$Num,PHASE     => WAITING,KIBITZERS => [],PLAYERS   => [],INFO      => \'\',RED5      => \'\',TALON     => [],TABLE     => {},ROUND     => 0,PASS_ROUND => 0,START     => undef,TURN      => undef,NPASSED   => 0,HOLDER    => undef,WHISTER1  => undef,WHISTER2  => undef,ACTIVE    => undef,PASSIVE   => undef,SHOW      => undef,BEFORE    => undef,SUIT1     => undef,TRUMP     => undef,WINNER    => undef,};

        $Games{$Num} = $game;
        bless($game,$pkg);
}
在对象中,我有很多哈希和列表引用,这些引用经常需要重置。例如,当游戏回合结束时(一种情况:当所有玩家通过时),我将只调用$ player-> {CARDS} = {};将玩家手中的纸牌数量减少到0。 我的问题是分配[]和{}是否足够好,还是太昂贵,因为perl解释器将在内部分配(或分配内存的任何方式)这些新的哈希和数组对象(真的吗?口译员足够聪明吗?)。 我正在使用(并且不想升级)库存的CentOS perl软件包:
This is perl,v5.8.8 built for x86_64-linux-thread-multi
在4GB机器上使用CentOS 5.6 / 64位,最高晚上同时有500名玩家。我的perl进程(一个非派生的守护进程,轮询TCP套接字)现在使用:
top - 13:50:07 up 13 days,3:25,1 user,load average: 2.64,3.36,3.46
Tasks: 179 total,2 running,177 sleeping,0 stopped,0 zombie
cpu0  :  3.6%us,0.3%sy,0.0%ni,96.0%id,0.0%wa,0.0%hi,0.0%si,0.0%st
cpu1  :  6.0%us,1.3%sy,92.7%id,0.0%st
cpu2  : 13.7%us,85.3%id,0.7%wa,0.0%st
cpu3  : 42.7%us,1.7%sy,54.6%id,0.3%hi,0.7%si,0.0%st
Mem:   4018280k total,2831016k used,1187264k free,313128k buffers
Swap:  7999472k total,13612k used,7985860k free,1775196k cached

  PID USER      PR  NI  VIRT  RES  SHR S %cpu %MEM    TIME+  COMMAND
13685 afarber   15   0  112m  46m 2704 R 41.8  1.2 176:45.14 pref.pl
谢谢! 亚历克斯     

解决方法

        优化规则是 别。 …还没有。 优化之前进行配置。 在另一条评论中,您说您没有性能问题,因此您仍然处于规则1。 至于如何清除数组和哈希,有一个潜在的陷阱要避免。优良作法是始终返回对象的私有数据的副本。考虑
#! /usr/bin/env perl

use strict;
use warnings;

package My::Class;

sub new {
  my($class,@a) = @_;
  bless { a => \\@a } => $class;
}

sub a {
  my($self) = @_;
  $self->{a};
}

package main;

my $obj = My::Class->new(1,2,3);

my $a = $obj->a;
print \"@$a\\n\";

push @$a,qw/ foo bar /;

my $b = $obj->a;
print \"@$b\\n\";
它的输出是 1 2 3 1 2 3 foo酒吧 返回对私有数据的引用为进行不受控制且可能令人惊讶的修改提供了一个句柄。 如果您的代码共享引用,请确保清除相同的数组和哈希,而不要创建对新数组和哈希的引用。否则,其他所有人将继续使用旧数据,而不会知道任何更改。用Perl的话来说,
@{ $game->{PLAYERS} } = ();
而不是
$game->{PLAYERS} = [];
    ,        您的样本是个好习惯。 Perl在基于RHEL的系统(包括CentOS)上存在性能问题。 RedHat构建的软件包比Perl慢得多。您应该尝试使用ActiveState的构建或Perl的新构建(如果需要,可以在/ opt / perl514中构建Perl 5.14,这并不难),以查看是否获得了更好的性能。     ,        我对此进行了搜索,因为我认为这是一个有趣的问题,但是我没有找到确切的数字。 但是,这里有一些我发现的文章: 有关基准测试以及Perl如何使用RAM的很多信息 有关如何编写“更快”的应用程序的一些提示 如果需要,可以使用一些工具来优化程序