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

标签 perl performance memory-management reference

我有 a card game - 用 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);
}

在对象中,我有许多哈希和列表引用,我经常需要重置它们。例如,当一个游戏回合结束时(一种情况:当所有玩家都通过时),我会调用 $玩家->{卡片} = {}; 将玩家手牌的数量减少到0。

我的问题是如果分配 [] 和 {} 是一种足够好的做法,或者如果它太昂贵 ,因为 perl 解释器将在内部 malloc(或它分配内存的任何操作)那些新的哈希和数组对象(真的吗?还是解释器足够聪明?)。

我正在使用(并且不想升级)库存的 CentOS perl 软件包:
This is perl, v5.8.8 built for x86_64-linux-thread-multi

使用 CentOS 5.6/64 位,在 4GB 机器上,最大。晚上同时有 500 名玩家。我的 perl 进程(一个非 fork 守护进程,轮询 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,  0.0%ni, 92.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu2  : 13.7%us,  0.3%sy,  0.0%ni, 85.3%id,  0.7%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu3  : 42.7%us,  1.7%sy,  0.0%ni, 54.6%id,  0.0%wa,  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

谢谢!
亚历克斯

最佳答案

rules of optimization

  • 不。
  • 不要……还没有。
  • 优化前的配置文件。

  • 在另一条评论中,您说您没有性能问题,所以您仍然遵循规则 1。

    至于如何清除数组和散列,有一个潜在的陷阱需要避免。好的做法是始终返回对象私有(private)数据的副本。考虑
    #! /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 bar

    Returning a reference to private data gives a handle for making uncontrolled and likely surprising modifications.

    If your code is sharing references, be sure to clear the same arrays and hashes rather than creating references to new ones. Otherwise, everyone else will go on using the old data without knowing anything has changed. In Perl terms, write

    @{ $game->{PLAYERS} } = ();
    

    而不是
    $game->{PLAYERS} = [];
    

    关于Perl:分配 [] 或 {} 是否昂贵?如何快速重置数字/关联数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6357852/

    相关文章:

    perl - Perl 中的非致命处理错误

    perl - 使用 Mozrepl 使用 WWW::Mechanize::FireFox 创建缩略图 - 一些调试尝试

    perl - 在 Perl 中,如何向操作系统释放内存?

    ios - UIImage不释放内存

    javascript - WebSocket频繁onmessage零拷贝

    perl - 使用 DateTime::Format::Strptime 将字符串转换为日期

    linux - 需要删除特定 block

    java - 检测字符串是否包含特定字符的最快方法

    c# - 在 C# 中搜索子目录

    Android 内部 URI 架构原因