in reply to Help in improving Performance of WinConsole makeFullBackBuffer

This is untested! You'll need to check it carefully.

First thing to look at is the inner loop. And the first thing I noticed there is that these lines are loop invariant.

$destRow = $current->{'rowTop'} + $row - 2; if ($destRow>$screen->{'height'}) { $destRow = $screen->{'height'}; }

(Ie They do not vary with the value of the inner loop counter), so they should be moved outside.

Next, these three lines respectively:

$backAtt[$destRow][$destCol] = $current->{'backAtt'}[$row - 1][$col - 1]; $self->{'zBuffer'}[$destRow][$destCol] = $active; substr($backTxt[$destRow], $destCol, 1) = substr($current->{'backTxt'}[$row - 1],$col - 1, 1);

  1. Copy a slice of an array element by element;

    Which can be done more efficiently by an array slice assignment.

  2. Assign to an array slice element-wise.

    Again, an array slice assignment.

  3. Copy a substr byte-wise.

    Can be replaced by a single substring assigment.

For that to happen, you need to calculate the source and destination start points and the width.

Putting that together I get:

sub makeFullBackBuffer { my ($self) = @_; my (@backAtt, @backTxt, $screen, $current, $destCol, $destRow, $ac +tive); $screen = $self->{miniwin}[ 0 ]; for( 1 .. $screen->{height} ) { push @backTxt, ' ' x $screen->{width}; push @backAtt, [ (0) x $screen->{width} ]; } for $active (reverse @{ $self->{winStack} } ) { $current = $self->{miniwin}[ $active ]; for my $row ( 1 .. $current->{height} ) { $destRow = $current->{rowTop} + $row - 2; $destRow = $screen->{height} if $destRow>$screen->{height} +; my $colMin = $current->{colTop} - 1; my $colMax = min( $screen->{width}, $current->{colTop} + $screen->{width} - 2 ); my $cols = $colMax - $colMin +1; @{ $backAtt[ $destRow ] }[ $colMin .. $colMax ] + = @{ $current->{backAtt}[ $row - 1 ] }[ 0 .. cols ] +; @{ $self->{zBuffer}[$destRow] }[ $colMin .. $colMax ] = ( $active ) x $cols; substr( $backTxt[ $destRow ], $colMin, $cols ) = substr( $current->{backTxt}[ $row - 1 ], 0, $cols ); } } return \( @backAtt, @backTxt ); }

Looking at that, I see that you could simplify the $destRow also, but as-is--assuming my logic is not too screwed, you could (maybe) see an order of magnitude improvement through the elimination of the inner loop.

Update:One thing you might consider is that Win32::Console gives access to the console apis and they allow the attachment of mutliple buffers to a screen which can be switched very quickly. The api also provides primatives for copying rectangular windows of both text and attributes (and introspection), which would be far more efficient than the role-your-own equivalents in the module you're using--but the switchover would probably involve a considerable amount of work.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^2: Help in improving Performance of WinConsole makeFullBackBuffer
by NateTut (Deacon) on Apr 28, 2009 at 14:15 UTC
    Thanks for your suggestions. I will try them out.
Re^2: Help in improving Performance of WinConsole makeFullBackBuffer
by NateTut (Deacon) on Apr 28, 2009 at 19:31 UTC
    I wish I could use a more "modern" module, like Win32::Console but this is going to run on Solaris and a bit out of date Perl (v5.6.1 ) as well. Unfortunately I can't get a newer Perl version installed and there's no C compiler either so I can't install my own version either.
      I wish I could use a more "modern" module, like Win32::Console but this is going to run on Solaris and a bit out of date Perl (v5.6.1 )

      I'm pretty sure that Win32::Console was around and working in 5.6.1 days...but no matter as it wouldn't run on Solaris! (It is Win32 (Windows only!)).

      My mistake. I assumed from the "Win" in WinConsole that it was a Windows module.

      Anyway, I hope that the refactoring I did will work for you.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        It was relatively bug free, you missed one $ but I do that all the time. I'm currently working an issue where it seems to not be capturing part of the screen at least it hit an undefined array element. I think it I can get it worked out it will be much faster. Thanks for your help