我的Rose :: DB :: Object编译时间太慢了吗?

时间:2009-08-06 08:00:01

标签: perl

我打算从Class :: DBI迁移到Rose :: DB :: Object,因为它的结构很好,而且与CDBI和DBIC相比,RDBO的速度更快。

然而在我的机器上(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分钟间隔 - 所以是的,编译时间在这里至关重要......

Jonathan Rockway的App :: Persistent似乎很有趣,但是它(当前)限制只允许一次运行一个应用程序并不适合我的目的。当我们终止客户端时,它也有问题,服务器进程仍在运行...

3 个答案:

答案 0 :(得分:5)

Rose::DB::Object只包含(或来自其他模块的引用)比Class::DBI更多的代码。从好的方面来看,它还有many more features,而much faster at runtime比Class :: DBI。如果您关注编译时间,那么最好的办法是尽可能少地加载代码(或者获得更快的磁盘)。

另一个选项是在元数据对象中将auto_load_related_classes设置为false。要尽早做到全局,可能需要您创建一个Metadata子类,然后将其设置为公共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元数据属性的默认值为真。

答案 1 :(得分:3)

如果编译时间是一个问题,有一些方法可以减少影响。一个是PPerl,它将一个普通的Perl脚本放入一个编译一次的守护进程中。您需要进行的唯一更改(当然,在安装之后)是shebang系列:

#!/usr/bin/pperl

另一种选择是代码编写客户端/服务器模型程序,其中大部分工作由加载昂贵模块的服务器和仅通过套接字或管道与服务器交互的瘦脚本完成。

你还应该看看App::Persistentarticle,这两个都是由Jonathan Rockway(又名jrockway)撰写的。

答案 2 :(得分:1)

这在这里看起来几乎是戏剧性的:

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

当然,你应该问问自己编译时间对你的特定问题有多重要。什么源代码更容易为您维护。