我想知道调用通过 Class::MethodMaker 创建的 getter/setter 时发生的调用顺序到底是什么?

MethodMaker 定义的 getter/setter 比原生的(在模块中覆盖)成本高多少?

有帮助吗?

解决方案

对于您有关 Class::MethodMaker 性能的问题,我没有简单的答案。正如前面提到的,您可以使用调试器来了解幕后发生了什么。但是,我知道 Class::MethodMaker 会生成 巨大的 安装时的代码量。这对我来说意味着三件不同的事情:

  1. 关于运行时,它是 大概 在整个方法生成器中速度更快的一侧。否则为什么要在安装时生成大量代码呢?
  2. 它会在您的磁盘上安装 O(兆字节)的代码!
  3. 编译时可能会很慢,具体取决于为简单用例加载生成代码的哪些部分。

你真的需要花几分钟思考一下你真正需要什么。如果您想要自动生成简单的访问器方法,但需要手动编写更复杂的内容,可以查看 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” “运行脚本;但预计会有很多输出!)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top