]> Sergey Matveev's repositories - public-inbox.git/commitdiff
release large (non ref) scalars using `undef $sv'
authorEric Wong <e@yhbt.net>
Sun, 5 Apr 2020 07:53:47 +0000 (07:53 +0000)
committerEric Wong <e@yhbt.net>
Sun, 5 Apr 2020 22:06:20 +0000 (22:06 +0000)
Using `undef EXPR' like a function call actually frees the heap
memory associated with the scalar, whereas `$sv = undef' or
`$sv = ""' will hold the buffer around until $sv goes out
of scope.

The `sv_set_undef' documentation in the perlapi(1) manpage
explicitly states this:

  The perl equivalent is "$sv = undef;". Note that it doesn't
  free any string buffer, unlike "undef $sv".

And I've confirmed by reading Dump() output from Devel::Peek.

We'll also inline the old index_body sub in SearchIdx.pm to make
the scope of the scalar more obvious.

This change saves several hundred kB RSS on both -index and
-httpd when hitting large emails with thousands of lines.

lib/PublicInbox/SearchIdx.pm
lib/PublicInbox/View.pm
lib/PublicInbox/ViewDiff.pm

index 89d8bc2b282dbf64bc71d87b1d1e1fb66b4fef24..9a5484e30b81b8ac29bb9bbfa43816ac6ee04210 100644 (file)
@@ -275,22 +275,8 @@ sub index_diff ($$$) {
        index_text($self, join("\n", @xnq), 1, 'XNQ');
 }
 
-sub index_body ($$$) {
-       my ($self, $txt, $doc) = @_;
-       if ($doc) {
-               # does it look like a diff?
-               if ($txt =~ /^(?:diff|---|\+\+\+) /ms) {
-                       index_diff($self, $txt, $doc);
-               } else {
-                       index_text($self, $txt, 1, 'XNQ');
-               }
-       } else {
-               index_text($self, $txt, 0, 'XQUOT');
-       }
-}
-
 sub index_xapian { # msg_iter callback
-       my ($part, $depth, @idx) = @{$_[0]};
+       my $part = $_[0]->[0]; # ignore $depth and @idx
        my ($self, $doc) = @{$_[1]};
        my $ct = $part->content_type || 'text/plain';
        my $fn = $part->filename;
@@ -300,11 +286,24 @@ sub index_xapian { # msg_iter callback
 
        my ($s, undef) = msg_part_text($part, $ct);
        defined $s or return;
+       $_[0]->[0] = $part = undef; # free memory
 
        # split off quoted and unquoted blocks:
        my @sections = PublicInbox::MsgIter::split_quotes($s);
-       $part = $s = undef;
-       index_body($self, $_, /\A>/ ? 0 : $doc) for @sections;
+       undef $s; # free memory
+       for my $txt (@sections) {
+               if ($txt =~ /\A>/) {
+                       index_text($self, $txt, 0, 'XQUOT');
+               } else {
+                       # does it look like a diff?
+                       if ($txt =~ /^(?:diff|---|\+\+\+) /ms) {
+                               index_diff($self, $txt, $doc);
+                       } else {
+                               index_text($self, $txt, 1, 'XNQ');
+                       }
+               }
+               undef $txt; # free memory
+       }
 }
 
 sub add_xapian ($$$$) {
index 1e53d8dc2ae133d7e58ac898021c632e618bb597..ddd94e48f730a2a493f913d9a43f3b6fd9dd1ac2 100644 (file)
@@ -566,7 +566,7 @@ sub add_text_body { # callback for msg_iter
 
        # split off quoted and unquoted blocks:
        my @sections = PublicInbox::MsgIter::split_quotes($s);
-       $s = '';
+       undef $s; # free memory
        my $rv = $ctx->{obuf};
        if (defined($fn) || $depth > 0 || $err) {
                # badly-encoded message with $err? tell the world about it!
@@ -587,7 +587,7 @@ sub add_text_body { # callback for msg_iter
                        # regular lines, OK
                        $$rv .= $l->to_html($cur);
                }
-               $cur = undef;
+               undef $cur; # free memory
        }
 
        obfuscate_addrs($ibx, $$rv) if $ibx->{obfuscate};
index f7422712aa4516818a22183a0630f729bb1b2f0a..3d6058a93b5b528e83aa2e8b83b53c50e05043dc 100644 (file)
@@ -192,7 +192,7 @@ sub flush_diff ($$) {
        my ($ctx, $cur) = @_;
 
        my @top = split($EXTRACT_DIFFS, $$cur);
-       $$cur = undef;
+       undef $$cur; # free memory
 
        my $linkify = $ctx->{-linkify};
        my $dst = $ctx->{obuf};