JosiahBryan has asked for the wisdom of the Perl Monks concerning the following question:
Greetings, Monks --
Working on a text canvas (attributes, characters, etc.) - PCI::Telnet::GUI::Canvas is the name. (Can post entire module if needed.) Here's a simple example of how it's used:
my $can = PCI::Telnet::GUI::Canvas->new(10,40); $can->fill([ON_YELLOW,BOLD,WHITE],0,0,$can->height,$can->width,HOR); my $c2 = PCI::Telnet::Canvas->new(5,10); $c2->box(0,0,$c2->height-2,$c2->width-2,ON_WHITE,BLACK,1); $can->render_canvas(2,2,$c2); print $can->to_string(20,10), "\n\n";
In a recent dprofpp (clear;perl -d:DProf -MPCI::Telnet::GUI::Canvas -e 1; dprofpp), it was reported that the two functions below use ~80% (83.6 3.122 3.243 1496 0.0021 0.0022 PCI::Telnet::GUI::Canvas::iloop) of the program processing time (under two different usages. In one test case, it was _atlayer, in another test case, it was iloop.)
Any advice from the Monks? Rewrite in C using Inline::C? Any perl tricks to optimize the iloop to make it go faster? Is there something I should do to clean up the code? My apologies for asking what seems to me to be a rather seemingly-simple question - but I'm at my wits end as far as optimizing the code.
Need to optimize:
use constant AS_BG => 0; use constant AS_FG => 1; use constant AS_U => 2; use constant AS_BLINK => 3; use constant AS_BOLD => 4; # clone is from the Clone module on CPAN. Tried using Clone::Fast, but + it added .05 sec to running time when this function was called ~6000 +x in .25 seconds. sub _atlayer { #$_[0] = shift; local $_ = clone($_[1]); #$_->{$_} = $_[1]->{$_} foreach keys %{$_[1]}; $_->[AS_BG] = $_[0]->[AS_BG] if !$_->[AS_BG]; $_->[AS_FG] = $_[0]->[AS_FG] if !$_->[AS_FG]; $_->[AS_U] = $_[0]->[AS_U] if $_->[AS_U] < 0; $_->[AS_BOLD] = $_[0]->[AS_BOLD] if $_->[AS_BOLD] < 0; $_->[AS_BLINK] = $_[0]->[AS_BLINK] if $_->[AS_BLINK] < 0; return $_; }
and
# iloop is the inner loop of the canvas rendering function. # I put it in a separate sub so that DProf could show it # apart from the main loop - and it gets 79% of the # processing time under one scenario. sub iloop($$$) { my ($line,$arow,$sw,$lat,$blank) = @_; my ($atr,$chr,$col,@a); for $col (0..$sw) { $chr = $line->[$col]; $atr = $arow->[$col]; push @a, _attr($atr) if #!_ateq($lat,$atr); $lat->[AS_BG] ne $atr->[AS_BG] || $lat->[AS_FG] ne $atr->[AS_FG] || $lat->[AS_U] != $atr->[AS_U] || $lat->[AS_BOLD] != $atr->[AS_BOLD] || $lat->[AS_BLINK] != $atr->[AS_BLINK]; push @a, defined $chr ? $chr : $blank; $lat = $atr; } return join '', @a; }
|
|---|