in reply to Re^2: Out of memory problems
in thread Out of memory problems

Hmm. I'm not surprised your processing is slow. Converting the whole 3 GB to ascii-ized binary will produce a 24 GB file. Then search/replace on that can convert back as separate stages?

Looking at your regex, it looks like your patterns are probably byte aligned? Very few processes produce data that is not...but I realise that it is possible. This how would tackle the task assuming tha the data is byte aligned.

The technique is called a 'sliding buffer'. You read a buffer of at least double the size of the thing you are looking for. In this case, 384 x 2 = 768 bytes. You then apply the regex to the whole of that buffer, write out the first half of it, move the second half to the front, top it up from the input file and re-apply the regex to the whole thing.

Note. That is a simplified description and the following code implements that simplified description by way of example only. It isn't tested and almost certainly won't work as is.

#!/usr/local/bin/perl -w use strict; open IN, '< :raw', $ARGV[ 0 ] or die "$ARGV[ 0 ] : $!"; open OUT, '> :raw', $ARGV[ 1 ] or die "$ARGV[ 1 ] : $!"; my $buffer; sysread IN, $buffer, 384, 384; do{ ## Move the second half of the buffer to the front. $buffer = substr( $buffer, 384 ); ## and overwrite it with a new chunk sysread IN, $buffer, 384, length( $buffer ); ## Apply the regex $buffer =~ s[ \xF4 . ## The marker byte plus friend ( .{190} ) ## 1520 bits to retain \xF4 . ## Second marker + friend ( .{58} ) ## 464 bits to retain .{132} ## 1056 bits to discard ][$1$2]xg; ## Write out the first half of the buffer syswrite OUT, $buffer, 384; } until eof IN; close IN; close OUT;

The are some further complications that need to be addressed.

Processing your 3 GB this way should take no more than 1/2 hour if you can avoid the packing/unpacking. And not much more than a couple of hours if you cannot. These are ballpark figures!

I hope that rather sketchy explaination makes some kind of sense. Good luck.


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

Replies are listed 'Best First'.
Re^4: Out of memory problems
by tperdue (Sexton) on Oct 21, 2004 at 21:45 UTC
    Thanks for that insight. I am working on a byte boundary. If I know exactly the bytes I need to keep and the ones I need to throw away is there a simpler method. I will need to extract the same byte positions in every 384 bytes. Using a substituation was the only way I knew how to do it but sounds like you have alot more experience with this. I tried to edit the file using hex in the files original state (which is packed binary on a sun machine running Solaris 5.6) but for every hex character I removed 2 bytes would be extracted. Any thoughts on this. And thanks for the help.

      Okay, knowing that the bit patterns are byte aligned and the records are 384 bytes each makes thing much easier. The following program should do the trick quite efficiently.

      #! perl -slw use strict; use bytes; ## Force byte semantic rather than (unicode) character sema +ntics. ## Maybe unnecessary, but it won't hurt. ## Using ':raw' is (roughly) equivalent to using [binmode] open IN, '< :raw', $ARGV[ 0 ] or die "$ARGV[ 0 ] : $!"; open OUT, '> :raw', $ARGV[ 1 ] or die "$ARGV[ 1 ] : $!"; local $/ = \384; ## Read file in 384 byte chunks. ## The only magic here is that ## a) we are reading the file in 384 byte chunks ## b) The unpack format extracts just the bits we wish to retain ## from the exact offsets we need. ## x2 - skips the xF4 x?? bytes ## A190 - returns the 190 bytes we need to retain ## x2 - skips the second xF4 x?? bytes ## A58 - returns the next 58 bytes. ## - the remaining 132 bytes from the buffer are discar +ded. while( <IN> ) { print OUT unpack 'x2 A190 x2 A58', $_; } close IN; close OUT;

      In theory, the following 'one-liner' (I've wrapped it to save PM the bother) would also work.

      If you have the time/patience/enthusiasm to try it, I'd love to know if it does.

      You will have to twiddle the "s -v- 's issue if you're on a non-Win32 platform.

      perl -C0 -mbytes -e"BEGIN{$/=\384}" -ne"print unpack 'x2 A190 x2 A58', $_" <infile >outfile

      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re^4: Out of memory problems
by tperdue (Sexton) on Oct 22, 2004 at 15:57 UTC
    I tried the code you mentioned with a few tweeks but am not being successful. The first 4 frames are good but after the patterns I want to remove are still there. I don't know why it would only appear to work for 4 frames and then quit. Any ideas??
      Any ideas??

      No, post the code and we can take a look,

      Incidentally, did you try this code? It should be considerably faster than any other method suggested here.


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
        I did try this code and it seems to work for about 3-4 frames and then it starts to slip a few bits. I will have to post the code on Monday since the machine I'm doing this on is at work. But I did try the code you had linked as it was typed with the above results.