Почему Perl Math :: Complex занимает так много времени, когда я пробую acos (1)? - PullRequest
2 голосов
/ 12 марта 2010

Пытаясь профилировать мою 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) {

Спасибо за любую помощь!

Ответы [ 3 ]

5 голосов
/ 12 марта 2010

Строки 182 и 185 выдают предупреждение, если не найдено регулярное выражение. Таким образом, медлительность, вероятно, заключается не в выдаче предупреждений, а в сопоставлении с регулярным выражением.

Если профилировщик говорит, что эти строки выполняются, они выполняются. Если вы не вызываете их напрямую, загружаемый вами модуль может вызывать их косвенно. Если вы используете более продвинутый профилировщик (например, Devel :: NYTProf ), вы сможете увидеть график вызовов, чтобы определить, какая часть вашего кода в конечном итоге вызывает вызов медленного кода библиотеки.

4 голосов
/ 12 марта 2010

Редактировать Math/Complex.pm и положить

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

вокруг одной из строк, перечисленных выше. Это распечатает трассировку стека, и вы увидите, как именно вы попали в этот модуль.

1 голос
/ 12 марта 2010

Согласно документации по отладчику perl, вы можете настроить обработчик для сигнала INT. Затем, пока он работает, вы можете нажать Ctrl-C, и он войдет в отладчик. Затем введите T, чтобы получить обратную трассировку, и она должна показать вам, почему именно она содержится в коде Complex.pm. Поскольку вы проводите много времени в этом коде, вы, вероятно, попадете в него, но если вы этого не сделаете, попробуйте еще раз, пока не сделаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...