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.
This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

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 Jun. 4th, 2025 12:31 am
Powered by Dreamwidth Studios