题
我想知道调用通过 Class::MethodMaker 创建的 getter/setter 时发生的调用顺序到底是什么?
MethodMaker 定义的 getter/setter 比原生的(在模块中覆盖)成本高多少?
解决方案
对于您有关 Class::MethodMaker 性能的问题,我没有简单的答案。正如前面提到的,您可以使用调试器来了解幕后发生了什么。但是,我知道 Class::MethodMaker 会生成 巨大的 安装时的代码量。这对我来说意味着三件不同的事情:
- 关于运行时,它是 大概 在整个方法生成器中速度更快的一侧。否则为什么要在安装时生成大量代码呢?
- 它会在您的磁盘上安装 O(兆字节)的代码!
- 编译时可能会很慢,具体取决于为简单用例加载生成代码的哪些部分。
你真的需要花几分钟思考一下你真正需要什么。如果您想要自动生成简单的访问器方法,但需要手动编写更复杂的内容,可以查看 Class::Accessor::Fast。或者,如果您想要最快的访问器方法,请研究 Class::XSAccessor,其极其简单的方法作为 C/XS 代码运行,并且速度大约是最快 Perl 访问器的两倍。(笔记:我编写了后一个模块,所以对此持保留态度。)
另一条评论:如果您打算使用 PAR/PAR::Packer 工具包来打包您的应用程序,请注意 Class::MethodMaker 的大量代码会导致可执行文件明显变大,并且初始启动时间变慢。此外,C::MethodMaker 和 PAR 之间存在已知的不兼容性。但这可能被视为 PAR 错误。
其他提示
这正是调试工具的用途:)
看看 perl调试 文档,特别是有关分析的部分。
特别是,使用 perl -dDProf filename.pl 运行脚本将生成一个 tt.out 文件,dprofpp 工具(与 Perl 一起分发)可以从中生成报告。
我使用了以下简单的测试脚本:
#!/usr/bin/perl package Foo; use strict; use Class::MethodMaker [ scalar => ['bar'], new => ['new'] ]; package main; use strict; my $foo = new Foo; $foo->bar('baz'); print $foo->bar . "\n";
使用 perl -d:DProf methodmakertest.pl 运行它,然后在输出上使用 dprofpp 给出:
[davidp@supernova:~/tmp]$ dprofpp tmon.out Class::MethodMaker::scalar::scal0000 has 1 unstacked calls in outer Class::MethodMaker::Engine::new has 1 unstacked calls in outer AutoLoader::AUTOLOAD has -2 unstacked calls in outer Total Elapsed Time = 0.08894 Seconds User+System Time = 0.07894 Seconds Exclusive Times %Time ExclSec CumulS #Calls sec/call Csec/c Name 25.3 0.020 0.020 4 0.0050 0.0050 Class::MethodMaker::Constants::BEG IN 25.3 0.020 0.029 12 0.0017 0.0025 Class::MethodMaker::Engine::BEGIN 12.6 0.010 0.010 1 0.0100 0.0100 DynaLoader::dl_load_file 12.6 0.010 0.010 2 0.0050 0.0050 AutoLoader::AUTOLOAD 12.6 0.010 0.010 14 0.0007 0.0007 Class::MethodMaker::V1Compat::reph rase_prefix_option 0.00 0.000 0.000 1 0.0000 0.0000 Class::MethodMaker::scalar::scal00 00 0.00 0.000 0.000 1 0.0000 0.0000 Class::MethodMaker::Engine::new 0.00 - -0.000 1 - - DynaLoader::dl_undef_symbols 0.00 - -0.000 1 - - Class::MethodMaker::bootstrap 0.00 - -0.000 1 - - warnings::BEGIN 0.00 - -0.000 1 - - warnings::unimport 0.00 - -0.000 1 - - DynaLoader::dl_find_symbol 0.00 - -0.000 1 - - DynaLoader::dl_install_xsub 0.00 - -0.000 1 - - UNIVERSAL::VERSION 0.00 - -0.000 1 - - Foo::new
两个最昂贵的调用是 Class::MethodMaker::Constants::BEGIN 和 Class::MethodMaker::Engine::BEGIN 块,它们显然仅在编译时调用,因此它们可能会稍微减慢脚本的编译速度,但后续对象创建/访问器使用不受其影响。
真正的问题是:有关系吗?
它是另一个访问器生成模块。这些模块都需要在速度/功能之间进行权衡。只需选择一个能够提供您所需一切的产品即可。访问器不太可能成为应用程序中的瓶颈。
@莱昂·蒂默曼斯
我知道存在一些速度/功能权衡,但想了解它有多好/坏?如果我能得到具体的实现,那就更好了,这样更容易做出决定。
除了我之前的回答之外,如果您想详细了解幕后发生的情况,请在调试器中以跟踪模式运行脚本(perl -d filename.pl,然后说“t”进行跟踪,然后说“r” “运行脚本;但预计会有很多输出!)。