LINUX.ORG.RU

функция, возвращает ссылки - плюсы и минусы.


0

0

Расмотрим два примера (пример 1 и пример 2)
#!/usr/bin/perl -w
use strict;
use Data::Dumper;

### пример 1
my %hash=getHash();
print "\$hash{'k1'}==$hash{'k1'}\n";
print "Hash: ", Dumper(\%hash);
### пример 2
my $refToHash=getRefToHash();
print "\$refToHash->{'k1'}==$refToHash->{'k1'}\n";
print "RefToHash: ", Dumper($refToHash);



### subrutines

sub getHash{ my %ret=('k1' => 'v1','k2' => 'v2');
return %ret;
}

sub getRefToHash{ my %ret=('k1' => 'v1','k2' => 'v2');
return \%ret;
}



Оба примера печатают то-же самое.
Вопрос:чем принципиально отличаются два метода возврата хашей: по значению и ссылкой (reference)? Кроме избавления от необходимости копировать хаш, чем череват второй подход ( в с/с++ все мне понятно, а тут - не очень: все-таки garbage collector-ы всякие, memory management и т.п....)
спасибо

anonymous

> Вопрос:чем принципиально отличаются два метода возврата хашей:

Принципиальное отличие какраз в том, что данные не копируются. Garbage collector работать будет с обоими.

Передача/получение ссылок выигрывают по производительности, но при reenterable коде нужно либо очень хорошо думать либо использовать первый метод.

nblx
()
Ответ на: комментарий от nblx

Например так:

[-- CUT --]
#!/usr/bin/perl

use warnings;
use strict;

use Thread;
use Data::Dumper;

sub Processor {
    my $hr = shift;

    grep { $hr->{$_}++ } keys(%{$hr});
}

my %Hash = ();

map { $Hash{'key'.$_} = $_ } (1..100);

Thread->new(Processor,\%Hash);

print Dumper(\%Hash);
[-- CUT --]

Если ошибся - огрызками не кидать. Скрипт не тестился и распространяется AS-IS :-)

nblx
()

> Вопрос:чем принципиально отличаются два метода возврата хашей:
> по значению и ссылкой (reference)?
>

Вопрос неверен по существу. Perl не умеет возвращать "хэши по
значению". Равно как и "массивы по значению". Perl умеет возвращать
или скаляр(scalar) или список скаляров (list).
При return %ret ты возвращаешь совсем не хэш - ты возвращаешь
list, который состит из чередующихся key и value этого %ret.
Но это просто list. Ты мог бы написать my @hash=getHash(); и получил
бы массив (для твоего примера) из четырех элементов.
То, что my %hash=getHash(); работает это просто свойство Perl - он
умеет присвоить list хэшу (при условии, что количество элементов в
list'е четное - то есть ключи и значения).
Если хэш небольшой - никакой разницы между твоими примерами не будет.
Если хэш большой - я бы возвращал именно reference, избегая копирования.

HTH

P.S. Никаких затруднений для garbage collectot'а не возникает
ни в каком случае.

Onanim
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.