当我尝试 acos(1) 时,为什么 Perl 的 Math::Complex 占用了这么多时间?

发布于 2024-08-24 10:24:49 字数 2406 浏览 6 评论 0原文

在尝试分析我的 Perl 程序时,我发现 Math::Complex 正在占用很多时间看起来像是某种警告。

另外,我的代码不应该生成或使用任何复数,所以我不确定它在 Math::Complex 中做什么。这是最昂贵线路的 FastProf 输出:

/usr/lib/perl5/5.8.8/Math/Complex.pm:182 1.55480 276232: _cannot_make("real part",      $re) unless $re =~ /^$gre$/;
/usr/lib/perl5/5.8.8/Math/Complex.pm:310 1.01132 453641: sub cartesian {$_[0]->{c_dirty} ?
/usr/lib/perl5/5.8.8/Math/Complex.pm:315 0.97497 562188: sub set_cartesian { $_[0]->{p_dirty}++; $_[0]->{c_dirty} = 0;
/usr/lib/perl5/5.8.8/Math/Complex.pm:189 0.86302 276232: return $self;
/usr/lib/perl5/5.8.8/Math/Complex.pm:1332 0.85628 293660: $self->{display_format} = { %display_format };
/usr/lib/perl5/5.8.8/Math/Complex.pm:185 0.81529 276232: _cannot_make("imaginary part", $im) unless $im =~ /^$gre$/;
/usr/lib/perl5/5.8.8/Math/Complex.pm:1316 0.78749 293660: my %display_format = %DISPLAY_FORMAT;
/usr/lib/perl5/5.8.8/Math/Complex.pm:1335 0.69534 293660: %{$self->{display_format}} :
/usr/lib/perl5/5.8.8/Math/Complex.pm:186 0.66697 276232: $self->set_cartesian([$re, $im ]);
/usr/lib/perl5/5.8.8/Math/Complex.pm:170 0.62790 276232: my $self = bless {}, shift;
/usr/lib/perl5/5.8.8/Math/Complex.pm:172 0.56733 276232: if (@_ == 0) {
/usr/lib/perl5/5.8.8/Math/Complex.pm:316 0.53179 281094: $_[0]->{'cartesian'} = $_[1] }
/usr/lib/perl5/5.8.8/Math/Complex.pm:1324 0.48768 293660: if (@_ == 1) {
/usr/lib/perl5/5.8.8/Math/Complex.pm:1319 0.44835 293660: if (exists $self->{display_format}) {
/usr/lib/perl5/5.8.8/Math/Complex.pm:1318 0.40355 293660: if (ref $self) {   # Called as an object method
/usr/lib/perl5/5.8.8/Math/Complex.pm:187 0.39950 276232: $self->display_format('cartesian');
/usr/lib/perl5/5.8.8/Math/Complex.pm:1315 0.39312 293660: my $self  = shift;
/usr/lib/perl5/5.8.8/Math/Complex.pm:1331 0.38087 293660: if (ref $self) { # Called as an object method
/usr/lib/perl5/5.8.8/Math/Complex.pm:184 0.35171 276232: $im ||= 0;
/usr/lib/perl5/5.8.8/Math/Complex.pm:181 0.34145 276232: if (defined $re) {
/usr/lib/perl5/5.8.8/Math/Complex.pm:171 0.33492 276232: my ($re, $im);
/usr/lib/perl5/5.8.8/Math/Complex.pm:390 0.20658 128280: my ($z1, $z2, $regular) = @_;
/usr/lib/perl5/5.8.8/Math/Complex.pm:391 0.20631 128280: if ($z1->{p_dirty} == 0 and ref $z2 and $z2->{p_dirty} == 0) {

感谢您的帮助!

While trying to profile my Perl program, I find that Math::Complex is taking up a lot of time with what looks like some kind of warning.

Also, my code shouldn't have any complex numbers being generated or used, so I am not sure what it is doing in Math::Complex, anyway. Here's the FastProf output for the most expensive lines:

/usr/lib/perl5/5.8.8/Math/Complex.pm:182 1.55480 276232: _cannot_make("real part",      $re) unless $re =~ /^$gre$/;
/usr/lib/perl5/5.8.8/Math/Complex.pm:310 1.01132 453641: sub cartesian {$_[0]->{c_dirty} ?
/usr/lib/perl5/5.8.8/Math/Complex.pm:315 0.97497 562188: sub set_cartesian { $_[0]->{p_dirty}++; $_[0]->{c_dirty} = 0;
/usr/lib/perl5/5.8.8/Math/Complex.pm:189 0.86302 276232: return $self;
/usr/lib/perl5/5.8.8/Math/Complex.pm:1332 0.85628 293660: $self->{display_format} = { %display_format };
/usr/lib/perl5/5.8.8/Math/Complex.pm:185 0.81529 276232: _cannot_make("imaginary part", $im) unless $im =~ /^$gre$/;
/usr/lib/perl5/5.8.8/Math/Complex.pm:1316 0.78749 293660: my %display_format = %DISPLAY_FORMAT;
/usr/lib/perl5/5.8.8/Math/Complex.pm:1335 0.69534 293660: %{$self->{display_format}} :
/usr/lib/perl5/5.8.8/Math/Complex.pm:186 0.66697 276232: $self->set_cartesian([$re, $im ]);
/usr/lib/perl5/5.8.8/Math/Complex.pm:170 0.62790 276232: my $self = bless {}, shift;
/usr/lib/perl5/5.8.8/Math/Complex.pm:172 0.56733 276232: if (@_ == 0) {
/usr/lib/perl5/5.8.8/Math/Complex.pm:316 0.53179 281094: $_[0]->{'cartesian'} = $_[1] }
/usr/lib/perl5/5.8.8/Math/Complex.pm:1324 0.48768 293660: if (@_ == 1) {
/usr/lib/perl5/5.8.8/Math/Complex.pm:1319 0.44835 293660: if (exists $self->{display_format}) {
/usr/lib/perl5/5.8.8/Math/Complex.pm:1318 0.40355 293660: if (ref $self) {   # Called as an object method
/usr/lib/perl5/5.8.8/Math/Complex.pm:187 0.39950 276232: $self->display_format('cartesian');
/usr/lib/perl5/5.8.8/Math/Complex.pm:1315 0.39312 293660: my $self  = shift;
/usr/lib/perl5/5.8.8/Math/Complex.pm:1331 0.38087 293660: if (ref $self) { # Called as an object method
/usr/lib/perl5/5.8.8/Math/Complex.pm:184 0.35171 276232: $im ||= 0;
/usr/lib/perl5/5.8.8/Math/Complex.pm:181 0.34145 276232: if (defined $re) {
/usr/lib/perl5/5.8.8/Math/Complex.pm:171 0.33492 276232: my ($re, $im);
/usr/lib/perl5/5.8.8/Math/Complex.pm:390 0.20658 128280: my ($z1, $z2, $regular) = @_;
/usr/lib/perl5/5.8.8/Math/Complex.pm:391 0.20631 128280: if ($z1->{p_dirty} == 0 and ref $z2 and $z2->{p_dirty} == 0) {

Thanks for any help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仙气飘飘 2024-08-31 10:24:49

除非正则表达式匹配,否则第 182 和 185 行会发出警告。因此,缓慢可能不是来自输出警告,而是来自正则表达式匹配。

如果探查器说这些行正在执行,那么它们就是。如果您不直接调用它们,则您加载的模块可能会间接调用它们。如果您使用更高级的分析器(例如 Devel::NYTProf),您将能够查看调用图来确定代码的哪一部分最终导致对缓慢的库代码的调用。

Lines 182 and 185 do a warning unless a regex matches. So the slowness is probably not from outputting warnings but rather doing the regular expression matching.

If the profiler says those lines are being executed, they are. If you aren't calling them directly, a module that you load may be calling them indirectly. If you use a more advanced profiler (such as Devel::NYTProf), you'll be able to see the call graph to determine what part of your code is ultimately causing the call to the slow library code.

熊抱啵儿 2024-08-31 10:24:49

编辑 Math/Complex.pm 并放置

use Carp;
Carp::cluck("in Math/Complex.pm");

上面列出的行之一。这将打印出堆栈跟踪,您将确切地看到如何进入该模块。

Edit Math/Complex.pm and put

use Carp;
Carp::cluck("in Math/Complex.pm");

around one of the lines listed above. This will print out a stack trace and you will see exactly how you are getting into this module.

浅黛梨妆こ 2024-08-31 10:24:49

根据 perl 调试器文档,您可以为 INT 信号设置一个处理程序。然后在运行时您可以键入 Ctrl-C,它将进入调试器。然后输入 T 来获取回溯,它应该准确地显示为什么它出现在 Complex.pm 代码中。由于您在该代码上花费了大量时间,因此您可能会陷入其中,但如果没有,请再试一次,直到做到为止。

According to the perl debugger doc, you can set up a handler for the INT signal. Then while it's running you can type Ctrl-C, and it will enter the debugger. Then type T to get a backtrace, and it should show you exactly why it is in the Complex.pm code. Since you are spending a lot of time in that code, you will probably land in it, but if you don't, try it again until you do.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文