【问题标题】:Is Moose really this slow?Moose真的这么慢吗?
【发布时间】:2015-04-28 00:41:44
【问题描述】:

我最近下载了 Moose。作为实验,我重写了 Moose 中的一个现有模块。这似乎是避免编写大量重复代码的便捷方法。我运行了模块的测试,我注意到它有点延迟。我用 -d:DProf 分析了代码,似乎只包括该行

no Moose;

在代码中将运行时间增加了大约 0.25 秒(在我的电脑上)。这是典型的吗?是我做错了什么,是我安装错了,还是我们真的应该期待这么多延迟?

【问题讨论】:

  • 0.25 秒对于计算机程序来说是一个非常长的初始化时间,hobbs。
  • 我的程序是一个 Web 应用程序,但它不会运行数小时或数天,它会在每个请求中运行一次。 0.25 的延迟是一个严重的缺陷。顺便说一句,为什么每个人都如此防御? “回答问题”发生了什么?问题是,我应该期待这种延迟,还是我做错了什么?答案似乎是“是的,您应该预料到这种延迟”。
  • @intuited:这是使用 mod_perl 的一大优势。
  • @Ether 没有一个头脑正常的人将 mod_perl 用于 Web 应用程序......它是用于使用 Perl 扩展 Apache,而不是构建网站。使用 FCGI。
  • 我不敢相信我支持 EC。但说真的,FastCGI 是最明智的选择。用 mod_perl 编写网站具有严重的可移植性影响。

标签: perl moose


【解决方案1】:

是的,使用 Moose 会受到一些惩罚。但是,这只是启动惩罚,而不是运行时;如果你写的一切都正确,那么在运行时事情会很快。

你是否也加入了这一行:

__PACKAGE__->meta->make_immutable;

当你no Moose;时在你所有的课上?调用此方法将使其(运行时)更快(以启动时间为代价)。特别是,对象构造和销毁在您的类中有效地“内联”,不再调用元 API。强烈建议您使您的类不可变。它使您的代码更快,编译时间成本很小。这在创建许多对象时尤其明显。12

但是,有时这个成本仍然过高。 如果您在脚本中使用 Moose,或者在编译时间占总使用时间很大一部分的其他方式中,请尝试使用 s/Moose/Moo/g - 如果您不使用 MooseX 模块,您可能会切换到Moo,其目标是更快(在启动时),同时保留 Moose 90% 的灵活性。

由于您正在使用 Web 应用程序,您是否考虑过使用 Plack/PSGI?

1From the docs of make_immutable, in Moose::Cookbook::Basics::Recipe7
2见还有 Stevan Little 的文章:Why make_immutable is recommended for Moose classes

【讨论】:

  • 有时快得多。很少有充分的理由让你的类不可变(这是你应该做的事情之一,只有在你知道原因并了解缺点和后果的情况下才应该这样做。)
  • $ time perl -Moose -E'has qw/foo isa Int is rw/; __PACKAGE__->meta->make_immutable if @ARGV; push @_, Class->new for 1..100_000; print scalar @_',然后运行相同的操作,只需附加一个 1 作为参数。你可以use Benchmark(.pm),但有时它甚至不接近。
  • Ether:Mouse 的目标是提供更快的启动时间,而不是“更快”。次要(相关!)目标是减少依赖项。
  • Err 和 make_immutable 会使 AIUI 启动更慢而不是更快。
  • 其实 Mouse 最初的目标是教 Sartak 如何编写元协议。其次是没有所有“元”开销的低深度 Moose。然后,Sartak 发现“Meta”是 Moose 的强大部分并继续前进,其他人拿起了 Mouse。
【解决方案2】:

Moose::Cookbook::FAQ:

听说Moose很慢,这是真的吗?

再说一次,这个很棘手,所以是和否。

首先,生活中没有什么是免费的,Moose 的某些功能确实比其他功能成本更高。 Moose 的政策也是只对您使用的功能收费,并尽我们最大的努力不为您不使用的功能的代码执行增加任何额外负担。当然,使用 Moose 本身确实会产生一些开销,但主要是编译时间。目前,我们确实有一些选项可用于获得您需要的速度。

目前,我们提供了使您的类不可变的选项,以提高速度。这将意味着编译时间成本稍高,但运行时速度的提高(尤其是在对象构造中)非常显着。这可以通过以下代码完成:

MyClass->meta->make_immutable();

我们会定期将 Class::MOP 的热点转换为 XS。 Florian Ragwitz 和 Yuval Kogman 目前正在研究一种将您的访问器和实例直接编译为 C 的方法,以便每个人都可以享受极速的 OO。

另一方面,我正在开发一个使用DancerMoose 的Web 应用程序。因为应用程序作为 HTTPD 守护程序运行,所以一旦服务器初始化,这些都不是真正相关的。性能似乎足以满足我对有限硬件或虚拟服务器的要求。

在这个项目中使用 Moose 和 Dancer 的另一个好处是,我的小型演示应用程序从大约 5000 行缩减到了不到 1000 行。

您希望您的应用依赖多少东西是您必须考虑的权衡之一。通过限制依赖关系,CGI 应用程序的响应速度更快。

【讨论】:

  • +1 这就是过去几年我编写原型或小型网络应用程序的方式(除了 s/Dancer/Squatting/)。添加反向代理 (en.wikipedia.org/wiki/Reverse_proxy),再也不用担心 CGI 了 :)
  • @Sinan - 你能澄清最后一行吗?这只是一个玩笑还是一些我不理解的尤达式智慧火花?
  • “使用 Moose 会引入很多需要编译的东西”似乎具有误导性。 Moose 启动速度较慢是因为它的元构造/内省/钩子的东西,而不是因为它编译代码。许多与 CGI.pm 共同使用的模块可以编译同样多甚至更多的代码。
  • @DVK 其他时候得解释一下,但这不是尤达之类的智慧。
  • @Sinan 出于好奇,您认为什么是中等硬件?睡眠这件事是个笑话,对吧? :)
【解决方案3】:

你的问题有点欺骗性。是的,Moose 有一个可衡量的启动成本,但在那之后并不慢。如果启动成本过高,您可以随时守护您的应用程序。

【讨论】:

  • 为什么是骗人的?直到昨天我才知道 Moose 这么慢,对此我感到相当惊讶。
  • @Kinopiko,ysth 认为slow 一词几乎不会调用“编译时间”成本……您不会说 KDE 4 很慢,因为编译需要 9 个小时。而且,您不会因为运行 init 脚本的时间而说 Linux 很慢……我不同意 ysth,我只是在解释我认为是他的论点。
  • 你又说了一遍:“Moose [is] 慢”...*你*知道你的意思是启动时间,但除非你澄清,否则其他人不会。
  • 但我实际上并不是指启动时间。我的整个程序运行完成大约需要 0.02 秒(即完成它正在做的事情并退出)。因此 0.25 秒已经很多了。
  • @Kinopiko - 你还在谈论启动时间(编译时间),这个类比仍然成立:编译 KDE 需要 9 个小时,即使你只是想上 Konsole 并找出内核版本,它不会使 KDE 变慢...尽管您在这里争论说 KDE 很慢 并省略 如果您只想获得全新安装的内核版本,除了与缓慢没有太大关系外,无论如何它都不是 KDE 的正常用例。
猜你喜欢
  • 1970-01-01
  • 2011-04-24
  • 2012-03-13
  • 2023-04-10
  • 2011-11-12
  • 2012-02-13
  • 2010-11-28
  • 2011-08-25
  • 1970-01-01
相关资源
最近更新 更多