Время компиляции моего Rose :: DB :: Object слишком медленное? - PullRequest
0 голосов
/ 06 августа 2009

Я планирую перейти от Class :: DBI к Rose :: DB :: Object из-за его хорошей структуры и жаргона, что RDBO быстрее сравнивается с CDBI и DBIC.

Однако на моей машине (linux 2.6.9-89, perl 5.8.9) время компиляции RDBO намного медленнее, чем CDBI:

$ time perl -MClass::DBI -e0
real    0m0.233s
user    0m0.208s
sys     0m0.024s

$ time perl -MRose::DB::Object -e0
real    0m1.178s
user    0m1.097s
sys     0m0.078s

Это лот другой ...

Кто-нибудь испытывает подобное поведение здесь?

Приветствие.


@ manni и @john: спасибо за объяснение модулей, на которые ссылается RDBO, оно наверняка ответит, почему время компиляции медленнее, чем CDBI.

Приложение не работает в постоянной среде. Фактически он вызывается несколькими одновременными заданиями cron, которые выполняются с интервалом в 2 минуты, 5 минут и x минут - так что да, время компиляции здесь крайне важно ...

Приложение Джонатана Роквея: :: Persistent кажется интересным, однако его (текущее) ограничение, позволяющее запускать одновременно только одно приложение, не подходит для моей цели. Также возникает проблема, когда мы убиваем клиента, процесс сервера все еще выполняется ...

Ответы [ 3 ]

5 голосов
/ 06 августа 2009

Rose :: DB :: Object просто содержит (или ссылки из других модулей) гораздо больше кода, чем Class :: DBI . С другой стороны, он также имеет намного больше функций и намного быстрее во время выполнения , чем Class :: DBI. Если вас беспокоит время компиляции, тогда вам лучше всего загрузить как можно меньше кода (или получить более быстрые диски).

Другой вариант - установить auto_load_related_classes в значение false в ваших объектах метаданных. Чтобы сделать это достаточно рано и глобально, вам, вероятно, потребуется создать подкласс Метаданные , а затем установить его как meta_class в вашем общем Rose :: DB :: Object базовый класс.

Отключение auto_load_related_classes означает, что вам придется вручную загружать связанные классы, которые вы на самом деле хотите использовать в своем скрипте. Это немного болезненно, но позволяет контролировать количество загружаемых классов. (Если у вас сильно взаимосвязанные классы, загрузка одного из них может привести к вытягиванию всех остальных.)

Возможно, вы могли бы иметь переменную окружения для управления поведением. Пример класса метаданных:

package My::DB::Object::Metadata;

use base 'Rose::DB::Object::Metadata';

# New class method to handle default
sub default_auto_load_related_classes
{
  return $ENV{'RDBO_AUTO_LOAD_RELATED_CLASSES'} ? 1 : 0
}

# Override existing object method, honoring new class-defined default
sub auto_load_related_classes
{
  my($self) = shift;

  return $self->SUPER::auto_load_related_classes(@_)  if(@_);

  if(defined(my $value = $self->SUPER::auto_load_related_classes))
  {
    return $value;
  }

  # Initialize to default
  return $self->SUPER::auto_load_related_classes(ref($self)->default_auto_load_related_classes);
}

А вот как это связано с базовым классом вашего общего объекта:

package My::DB::Object;

use base 'Rose::DB::Object';

use My::DB::Object::Metadata;

sub meta_class { 'My::DB::Object::Metadata' }

Затем установите для RDBO_AUTO_LOAD_RELATED_CLASSES значение true, когда вы работаете в постоянной среде, и оставьте значение false (и не забудьте явно загрузить связанные классы) для сценариев командной строки.

Опять же, это поможет, только если в данный момент вы загружаете больше классов, чем вам строго необходимо в конкретном скрипте, из-за значения по умолчанию истинного атрибута auto_load_related_classes Метаданные.

3 голосов
/ 06 августа 2009

Если время компиляции является проблемой, существуют способы уменьшить влияние. Одним из них является PPerl , который превращает обычный Perl-скрипт в демон, который компилируется один раз. Единственное изменение, которое вам нужно сделать (после его установки, конечно), это строка shebang:

#!/usr/bin/pperl

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

Вам также следует взглянуть на App :: Persistent и на эту статью , обе из которых были написаны Джонатаном Роквеем (он же jrockway ).

1 голос
/ 06 августа 2009

Здесь это выглядит почти так же драматично:

time perl -MClass::DBI -e0
real       0m0.084s
user       0m0.080s
sys        0m0.004s

time perl -MRose::DB::Object -e0
real       0m0.391s
user       0m0.356s
sys        0m0.036s

Боюсь, что часть различий можно объяснить количеством зависимостей в каждом модуле:

perl -MClass::DBI -le 'print scalar keys %INC'
46

perl -MRose::DB::Object -le 'print scalar keys %INC'
95

Конечно, вы должны спросить себя, сколько времени компиляции действительно имеет значение для вашей конкретной проблемы. И какой исходный код будет легче поддерживать для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...