You're only extracting the IP addresses, so let's find out how many you have.

$ perl -wE'say 5.5*1024 / length("Nov 17 11:09:25 proxy02 kernel: OUTP +UT LOGIN= OUT=eth0 SRC=11.11.11.0 DST=192.168.3.1 LEN=1420 TOS=0x00 P +REC=0x00 TTL=64 ID=10523 DF PROTO=TCP SPT=3128 DPT=1921 WINDOW=16659 +RES=0x00 ACK URGP=0\n")' 29.0309278350515

So you have about 30M IP addresses, many of which are duplicates.

$ perl -MDevel::Size=total_size -wE'my %h; for (1..100) { ++$h{ pack " +C4", 1,2,3,$_ } } say total_size(\%h)/100' 47.56

At a rate of roughly 50 bytes per IP, you'd need 30M * 50 bytes = 1.5GB just for the data. That's a lot, but it might be small enough to avoid getting fancy, especially since many are duplicates.

use strict; use warnings; my $fn_in = 'internal.out'; my $fn_ex = 'external.out'; my @internals = ( [ pack('C4', 10,0,0,0 ), pack('C4', 255,0,0,0 ) ], # [ pack('C4', 10,10,0,0 ), pack('C4', 255,255,0,0 ) ], [ pack('C4', 192,3,3,0 ), pack('C4', 255,255,254,0 ) ], [ pack('C4', 192,168,0,0 ), pack('C4', 255,255,0,0 ) ], # [ pack('C4', 192,168,24,0 ), pack('C4', 255,255,248,0 ) ], ); sub is_internal { my $packed_ip = shift; for (@internals) { return 1 if $packed_ip & $_->[1] eq $_->[0]; } return 0; } sub extract { open(my $fh_in, '>', $fn_in) or die("Can't create file $fn_in: $!\n"); open(my $fh_ex, '>', $fn_ex) or die("Can't create file $fn_ex: $!\n"); my %seen; while (<>) { my $ip = /DST=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ or next; my $packed_ip = pack('C4', split(/\./, $ip)); next if $seen{$packed_ip}++; print { is_internal($packed_ip) ? $fh_in : $fh_ex } "$ip\n"; } undef %seen; # Free mem. } sub sort { my ($fn) = @_; my @packed_ips; { open(my $fh, '<', $fn) or die("Can't open file $fn: $!\n"); while (<$fh>) { chomp; my $packed_ip = pack('C4', split(/\./, $ip)); push @packed_ips = $packed_ip; } } @packed_ips = sort @packed_ips; { open(my $fh, '>', $fn) or die("Can't create file $fn: $!\n"); for (@packed_ips) { my $ip = join('.', unpack('C4', $packed_ip)); print("$ip\n"); } } } sub main { extract(); sort_file($fn_in); sort_file($fn_ex); } main();

Using a trie instead of a hash would reduce memory usage, and it would provide the results in sorted order.

By the way, two of your internal ranges are redundant with other ranges. I commented them out.


In reply to Re: Out of memory inefficient code? by ikegami
in thread Out of memory inefficient code? by tuxtutorials

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.