Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re^2: help with memory leak

by crunch_this! (Acolyte)
on Apr 17, 2013 at 19:44 UTC ( [id://1029210]=note: print w/replies, xml ) Need Help??


in reply to Re: help with memory leak
in thread help with memory leak

Looks like I've got a slightly different version:

perl -v This is perl 5, version 14, subversion 2 (v5.14.2) built for MSWin32-x +86-multi-thread

uname -a didn't give me anything. I don't know what I did wrong

Do you want to know what leaktest -verbose has to say? If there's a way to copy/paste it rather than type it by hand it would be great to know...

What sort of values are assigned to $rep
In this question & in testing I use small values (like <100) just to see how well it works. Once it's polished I want to use numbers basically a big as my computer can handle, like 1000 or bigger. So I expect the haystack to be huge even without any memory leaks. & if my computer can't handle that I'll go to some cloud computing thing to do it.

What tests you're running
In addition to the ones mentioned already, I've tried is_cycle_ok(), weaken() & I don't remember what else.

How and where you're using %haystack (beyond the assignment you show)
I was thinking of creating all polynomials with integer solutions, whose derivatives also have integer solutions. So a hash where the keys are the solutions of the polynomials and corresponding values are the solutions of the derivatives. The subroutine below searches the derivatives' zeros for zero-sets that only contain "approximte" integers. Then a hash slice gets created with the keys I want & Dumper prints it out. Here are the threads
http://perlmonks.org/?node_id=1027571
http://perlmonks.org/?node_id=1028273

Here's the entire program, finished with assistance of user hdb who replied earlier in this node, & after changing a, b & c to x, y & z:

#!/usr/bin/perl -w #use strict; use warnings; use Data::Dumper; use Math::Polynomial::Solve qw! poly_derivative poly_roots !; use Math::Round qw! round !; use Devel::Size qw! size total_size !; use Scalar::Util qw! weaken isweak !; use Test::Memory::Cycle; use Test::LeakTrace; my %haystack; # $rep means right endpoint of the interval [0, $rep] my $rep = int 3; foreach my $x (3 .. $rep ) { foreach my $y (2 .. $x-1 ) { foreach my $z (1 .. $y-1 ) { # expanded form of x*(x - $x)*(x - $y)*(x - $z) # coeffs are in an array $haystack{"$x, $y, $z"} = [ poly_roots( poly_derivative( 1, -$x - $y - $z, $x*$y + $x*$z + $y*$z, -$x*$ +y*$z, 0 ) ) ]; } } } # for each zero in @zeros, assigns a truth value to whether or not it +is within 0.0001 of an integer (1=true, 0=false) sub is_approximately_an_integer { my $eps = 0.0001; while( my $x = shift ) { # need to use "round", "int" does not work! return 0 if abs( $x-round($x) ) > $eps; } return 1 } # this returns only the arrays but loses keys #print "\nSelected arrays\n"; my @wants = grep { is_approximately_an_integer( @$_ ) } values %haysta +ck; #print Dumper( @wants ); # this returns the keys #print "\nSelected keys...\n"; @wants = grep { is_approximately_an_integer( @{$haystack{$_}} ) } keys + %haystack; print Dumper( @wants ); # and you can get the arrays as well #print "\n...and the associated array.\n"; #print Dumper( @haystack{@wants} ); my $polys = $#wants + 1; # prints out the corresponding values from %haystack #if ( @wants ) { # print "\nWe found $polys polynomials!\n"; #} else { # print "No polynomials here. Try another interval.\n"; #}; my $size = size(\%haystack); my $total_size = total_size(\%haystack); print "\nThe size of haystack is $size bytes.\n"; print "The size of haystack including references is $total_size bytes. +\n"; my $sizewants = size(\@wants); my $totalsizewants = total_size(\@wants); print "\nThe size of wants is $sizewants bytes.\n"; print "The size of wants including references is $totalsizewants bytes +.\n";

Replies are listed 'Best First'.
Re^3: help with memory leak
by kcott (Archbishop) on Apr 18, 2013 at 05:16 UTC

    Don't worry about uname. What you've shown indicates we're using the same Perl version but completely different OSes: I'm using Mac OS X; you're using MS Windows.

    Be aware how the number of iterations grows with respect to $rep: 4 = 4; 5 = 10; 10 = 120; 20 = 1140; 100 = 161700; and so on.

    You didn't indicate how the code changes affected the leaks. My tests still show no leaks — I'm unable to reproduce your problem.

    I can't see any leak-related isues with %haystack; although, that doesn't mean there aren't any. I do note that you're populating @wants twice with what appears to be the same data:

    my @wants = grep { is_approximately_an_integer( @$_ ) } values %haysta +ck; # intervening comments here only @wants = grep { is_approximately_an_integer( @{$haystack{$_}} ) } keys + %haystack;

    Obviously, you only want one of those. Also, if %haystack is only used to populate @wants (you don't show any other usage in your code), consider whether the is_approximately_an_integer() filter might be better placed in the innermost loop (possibly doing away with %haystack altogether).

    -- Ken

      Changing the code doesn't change whether or not leaktrace detects any leaks, including putting the subroutine in the innermost loop. How could I do this without %haystack, since if there are actually no memory leaks I think that would probably be much less of a drag on my computer? & simpler is better imho. I'm open to anything that would work. The function no_leaks_ok says there aren't any leaks so I'm with you there but leaktrace -verbose says

        Going back to the Test::LeakTrace documentation, specifically the part I quoted in my original response, you'll see: "Thus, to trace true leaks, no_leaks_ok() ...". So, if the documentation is to be believed, and no_leaks_ok() is showing no leaks with the modified code, then it would follow that you now have no true leaks. Problem solved!

        In your code, the only use you show for %haystack is to conditionally populate @wants. So, rather than coding:

        my %haystack; ... $haystack{"$x, $y, $z"} = [ poly_roots( ... my @wants = grep { is_approximately_an_integer( @$_ ) } values %haysta +ck;

        I'm suggesting you do something like this (which does away with %haystack altogether):

        my @wants; ... push @wants, grep { is_approximately_an_integer( @$_ ) } [ poly_roots( ...

        -- Ken

      I'm suggesting you do something like this (which does away with %haystack altogether):
      my @wants; ... push @wants, grep { is_approximately_an_integer( @$_ ) } [ poly_roots( ...

      OK that works much better, more efficient & no problems of any kind with leaktrace or no_leaks_ok, etc. The reason I thought a hash would be a good idea was that I'm also interested in getting back the corresponding $x, $y, $z at the end. That's why the coeffecients look the way they do in the poly_derivative definition. Is there a way to do that without using a hash? If not I'd still gladly trade that for more efficiency because I can always integrate what I get, or I could just work with the coefficients rather than the zeros.

        Something like this perhaps:

        ... push @wants, map { { join('-', $x, $y, $z) => $_ } } grep { is_approximately_an_integer( @$_ ) } [ poly_roots( ...

        -- Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1029210]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2024-04-18 19:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found