2010-03-11 3 views
2

내 Perl 프로그램의 프로필을 만드는 동안 어떤 종류의 경고와 같이 보일 때 Math::Complex이 많은 시간을 차지하고있는 것으로 나타났습니다.왜 Perl의 Math :: Complex가 acos (1)를 시도 할 때 많은 시간을 소비합니까?

또한 내 코드에는 복잡한 숫자가 생성되거나 사용되어서는 안되기 때문에 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) { 

어떤 도움을 주셔서 감사합니다!

+0

'Math :: Trig'문제는 http://search.cpan.org/~jhi/Math-Complex-1.56/lib/Math/Trig.pm#Real-valued_asin_and_acos에 문서화되어 있습니다. 'acos_real'과'asin_real' 함수는 대안으로 제공됩니다. – mob

+0

BTW에서 코사인 값이 1 인 각도는 정확히 0입니다. 이는 가장자리 경우입니다. arcos (1)에 대한 반복적 인 해법은 가능한 한 가장 작은 수로 내려갈 것이지만, 0이 아닌 경우에는 여전히 그것을 놓칠 것이다. –

답변

4

편집 Math/Complex.pm하고 위의 라인 중 하나 주위에

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

을 넣어. 이렇게하면 스택 트레이스가 출력되고이 모듈에 어떻게 들어가는지 정확하게 알 수 있습니다.

+0

실제로 처음에 다른 두 가지 디버깅 제안을 시도했지만이 문제가 결국 해결되었습니다. 분명히 acos (1)을 취하면 Math :: Complex가 호출됩니다. 왜 불분명 한가요? – shino

5

라인 182와 185는 정규 표현식이 일치하지 않는 한 경고를 표시합니다. 따라서 느린 것은 경고를 출력하는 것이 아니라 정규식 일치를 수행하는 것입니다.

프로파일 러에서 해당 행이 실행 중임을 알리는 경우, 해당 행이 표시됩니다. 직접 호출하지 않으면로드 한 모듈이 간접적으로 호출 할 수 있습니다. 고급 프로파일 러 (예 : Devel::NYTProf)를 사용하는 경우 호출 그래프를보고 코드의 어떤 부분이 궁극적으로 느린 라이브러리 코드를 호출하는지 확인할 수 있습니다.

1

펄 디버거 문서에 따르면 INT 신호에 대한 처리기를 설정할 수 있습니다. 그런 다음 실행 중일 때 Ctrl-C를 입력하면 디버거로 들어갑니다. 그런 다음 T를 입력하여 백 트레이스를 가져 오면 Complex.pm 코드에있는 이유를 정확하게 보여야합니다. 당신이 그 코드에서 많은 시간을 소비하고 있기 때문에 아마 그 코드에 착륙 할 것입니다. 그러나 그렇지 않다면 다시 시도하십시오.

관련 문제