allter: (Default)
[personal profile] allter
Оказывается, код, содержащий меньшее количество my-переменных, может выполняться в разы дольше, чем код с большим их количеством.

Пример под катом:


  1. Первый код

    #!/usr/bin/perl
    use strict;
    package Aa;
    sub new {
    my $class = shift;
    return bless { @_ }, $class;
    }

    package main;
    my @aaa = map( Aa->new( ind => $_ ), ( 1 .. 1000000 ) );


  2. Второй код

    #!/usr/bin/perl
    use strict;
    package Aa;
    sub new {
    my $class = shift;
    my $self = bless { @_ }, $class;
    return $self;
    }

    package main;
    my @aaa = map( Aa->new( ind => $_ ), ( 1 .. 1000000 ) );



Первый код работает 22 cекунды против 6 секунд второго кода, то есть, почти в 4 раза больше.

>time perl fields_hashes.pl
0.01user 0.00system 0:21.48elapsed 0%CPU (0avgtext+0avgdata 8576maxresident)k
0inputs+0outputs (541major+0minor)pagefaults 0swaps

>time perl fields_hashes.pl
0.01user 0.01system 0:05.54elapsed 0%CPU (0avgtext+0avgdata 8576maxresident)k
0inputs+0outputs (541major+0minor)pagefaults 0swaps


Кстати, варианты с use fields qw(ind); работают:

  1. 8.78c. с конструктором вида:

    my $class = shift;
    my $self = fields::new( $class );
    $self->{ ind } = $_[1];
    return $self;

  2. 12.25c. с конструктором вида:

    my $class = shift;
    my $self = fields::new( $class );
    for( my $i = 0; $i < $#_; $i += 2 ) {
    $self->{ $_[ $i ] } = $_[ $i+1 ];
    }
    return $self;

  3. 14.51c. с конструктором вида:

    my $class = shift;
    my $self = fields::new( $class );
    %$self = ( %$self, @_ );
    return $self;

  4. 15.62c. с конструктором вида:

    my $class = shift;
    my $self = fields::new( $class );
    while ( my ( $key, $val ) = splice( @_, 0, 2) ) {
    $self->{ $key } = $val;
    }
    return $self;

  5. и 16.32c. с конструктором вида:

    my $class = shift;
    my $self = fields::new( $class );
    my $ary = { @_ };
    map( $self->{ $_ } = $ary->{ $_ }, keys %$ary );
    return $self;



Такая вот арифметика - видимо, связанная с особенностями размещения памяти и логикой построения внутренних структур.

Update: Сделал ещё варианты с использованием blessed массивов и скаляров в качестве классов, получились предсказуемые результаты. С массивами быстрее, чем с хэшами (4.79с.). И медленнее, чем со скалярами (3.62с., даже при том, что я ввёл в конструкторе my-переменную ind, которую и bless`ил).

Что ещё интересно, с тривиальным эмулятором обращений к классам вида (пример для blessed скаляров):

my $sum = 0;
$$_++ for ( @aaa );
$sum += $$_ for ( @aaa );

print "$sum\n";

, "массивный" вариант увеличивает время выполнения всего на 0.86с., что ненамного меньше "хэшовых" 1.2с (вариант с присваиванием через $self->{ ind } = $_[1];), и также ненамного больше скалярных 0.55с. (как в приведённом выше примере обращений).

Мораль: разница микроскопическая, но есть, а пользоваться надо любым удобным способом без попыток излишних оптимизаций, как завещает нам великий Wall.

Date: 2006-03-22 04:52 pm (UTC)
From: [identity profile] neithere.livejournal.com
пример убил

Date: 2006-03-22 10:26 pm (UTC)
From: [identity profile] neithere.livejournal.com
неожиданный. :)
я бы счел, что первый код будет быстрее =)

Profile

allter: (Default)
allter

October 2021

S M T W T F S
     12
3 456789
10111213141516
17181920212223
24252627282930
31      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 29th, 2025 11:41 pm
Powered by Dreamwidth Studios