Subscribed unsubscribe Subscribe Subscribe

「 bless は重い」は本当か

perl

よく「 Perl の bless() は重いので new() しまくるとパフォーマンス悪化につながる。シングルトン化せよ」みたいなのを聞く(ような気がする。気のせいかも)。

なので、

  1. ループ中で都度 new する方法
  2. インスタンスを使いまわす方法

で速度を測ってみた。

use Time::HiRes

# 7027.247 ms
{
    my $start = [ Time::HiRes::gettimeofday ];
    for (1..100_000) {
        Foo->new(map { $_ => $_ } 1..100);
    }
    print Time::HiRes::tv_interval($start) * 1000, "\n";
}
# 7297.862 ms
{
    my $start = [ Time::HiRes::gettimeofday ];
    for (1..100_000) {
        Foo->instance(map { $_ => $_ } 1..100);
    }
    print Time::HiRes::tv_interval($start) * 1000, "\n";
}

package Foo;

sub new {
    my ($class, %args) = @_;
    bless \%args, $class;
}

sub instance {
    my ($class, %args) = @_;
    state $instance ||= Foo->new;
    for my $key (keys %args) {
        $instance->{$key} = $args{$key};
    }
}

ほとんど一緒。

bless が重いという噂は聞き間違いで、 OO な実装が関数呼び出しな実装より遅くなるよ、という話だったのかもしれない。

See Also