Perl: стоит ли присваивать [] или {} дорого? Как быстро сбросить числовые / ассоциативные массивы? - PullRequest
4 голосов
/ 15 июня 2011

У меня карточная игра - написана на 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 будет malloc (или что бы он ни делал для выделенияпамять) эти новые объекты хеша и массива для внутреннего использования (будет ли это на самом деле? или интерпретатор достаточно умен?).

Я использую (и не хочу обновлять) стандартный пакет Perl CentOS:

This is perl, v5.8.8 built for x86_64-linux-thread-multi

с CentOS 5,6 / 64 бит, на машине 4 ГБ и макс.одновременно 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,  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

Спасибо!Alex

Ответы [ 3 ]

7 голосов
/ 15 июня 2011

правила оптимизации :

  1. Не.
  2. Не ... пока.
  3. Профиль перед оптимизацией.

В другом комментарии вы говорите, что у вас нет проблем с производительностью, поэтому вы все еще придерживаетесь правила 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 bar

Возвращение ссылки на личные данные дает возможность для неконтролируемых и вероятных неожиданных изменений.

Если ваш код делитсяссылки, обязательно очистите те же массивы и хэши , а не создавайте ссылки на новые.В противном случае все остальные будут продолжать использовать старые данные, не зная, что что-то изменилось.В терминах Perl напишите

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

вместо

$game->{PLAYERS} = [];
0 голосов
/ 15 июня 2011

Я сделал поиск по этому поводу, потому что я думаю, что это интересный вопрос, но я не нашел точных цифр.

Однако вот несколько статей, которые я нашел:

0 голосов
/ 15 июня 2011

Ваш пример - хорошая практика.

Существует проблема с производительностью Perl на системах на основе RHEL, включая CentOS.Пакет, созданный RedHat, значительно медленнее, чем должен быть Perl.Вам следует поэкспериментировать со сборкой ActiveState или новой сборкой Perl (вы можете собрать Perl 5.14 в / opt / perl514, если хотите, это не сложно), чтобы увидеть, улучшится ли производительность.

...