Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: Memory usage double expected

by harangzsolt33 (Chaplain)
on Oct 27, 2022 at 19:58 UTC ( #11147755=note: print w/replies, xml ) Need Help??


in reply to Memory usage double expected

I have noticed the SAME behavior in TinyPerl 5.8 running on Windows XP. I reserve a large amount of memory, let's say 20 MB using the 'x' operator. I want a string that is 20 million bytes and is filled with letter 'A' all the way. So, I do this : my $VAR = 'A' x 20000000; # And boom! It uses 40MB of memory. I used a memory viewer to look into the TINYPERL.EXE application to see what's going on. I thought, it will be filled with 00 41 00 41 00 41 because it might store the letters as Unicode, reserving two bytes for each character. But nope! That's not what happens. Perl literally creates a twice as many letter 'A's in memory than what I want!

Someone explained it this way: Since Perl sees that both the letter 'A' and the 20_000_000 are constants, it creates a backup copy in memory in order to use it later... Nah, that's not true. because you can replace the 20 million with a variable, and read the number from STDIN and whatever you punch in, it still fills up twice as many bytes with letter 'A's which makes no sense.

I have played around with this a little bit and discovered that if you use the vec() function, you can initialize a string without wasting memory. vec($A, 19999999, 8) = 0; will give you a string that is exactly 20 million bytes long filled with zero bytes. Now, if you do vec($A, 19999999, 8) = 65; it will still pad the string with zero bytes and insert a letter 'A' at the end. I would like to know if there's a way to tell vec() function to use some other character for padding. It always uses the zero byte as padding. So, to fill up the string with letter 'A's, I would probably create a for loop and repeat the following 5 million times: vec($A, $PTR++, 32) = 0x41414141; That'll give you a string with 20 million letter 'A's. But if you want to write 4 gigs of letter 'A's that'll take quite awhile! lol

If anybody knows a shortcut to initialize a string with letter 'A's QUICKLY and without using the 'x' operator, please, do tell me!!!

Replies are listed 'Best First'.
Re^2: Memory usage double expected
by kcott (Archbishop) on Oct 28, 2022 at 07:04 UTC

    G'day harangzsolt33,

    "vec($A, 19999999, 8) = 0; will give you a string that is exactly 20 million bytes long filled with zero bytes."

    All good so far. You have a string of the length you wanted. This works for me.

    "So, to fill up the string with letter 'A's, I would probably create a for loop and repeat the following 5 million times: ..."

    Or you could just do this once:

    $A =~ y/\0/A/;

    That works for me. I ran a few tests and that seems to take about five times longer than "$A = 'A' x 20_000_000". Run your own benchmarks, but I think you'd be better off with the 'x' operator.

    — Ken

Re^2: Memory usage double expected
by sectokia (Pilgrim) on Oct 28, 2022 at 05:23 UTC

    So the simple answer is to avoid having both sides of the 'x' operator as constants. For example, this will fix your situations:

    my $VAR = makeA(20000000); sub makeA { return 'A' x (shift) }

    This would also fix it:

    my $VAR = make20m('A'); sub make20m { return (shift) x 20000000 }

    The conclusion seems to be that perl the constant itself occupies memory, and then the variable gets its own copy of the constant.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2023-12-01 10:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?