IB2017 has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I'd like to hear your suggestions on how to improve speed in the following script (sorry if it is not so clean, but it is a dirty minimization of a big GUI project). The script mimics the insertion of a lot of data in a Tk Tablematrix with some formattings (adaptation of row hight to display all text in cell, coloring of rows, and indentation). The problem is speed and the bottleneck is the routine setHeight. Any pragmatic idea to reduce the loading time (improvements in the subrutine, different approach, etc.)?

use strict; use warnings; use Tk; use Tk::Font; use Tk::TableMatrix; #look my $BackgroundTableRow="#D0E1F9"; my $BackgroundTableHeader="red"; my $MainTableIpadx=2; my $MainTablePadx=2; #number of rows to print my $NumberRows=7000; our $arrayVar = {}; my $mw = MainWindow->new(); my $MainTable = createTABLE($mw); createTableRows($MainTable, $NumberRows); printData($MainTable, $NumberRows); MainLoop; sub createTABLE{ my $mw = shift; my $GuiFontData = $mw->Font(-family=> 'Arial', -size => 12); my ($rows,$cols) = (1, 3); foreach my $row (0..($rows-1)){$arrayVar->{"$row,0"} = "$row";} foreach my $col (0..($cols-1)){$arrayVar->{"0,$col"} = "$col";} my $MainTable = $mw->Scrolled('TableMatrix', -rows => $rows, -cols => $cols, -bg=>'white', -height => 4, -titlerows => 1, -titlecols => 0, -variable => $arrayVar, #-browsecommand => \&SelectTableRow, -coltagcommand => \&colSub, -resizeborders => "none", -wrap=>1, -multiline=>1, -relief => 'ridge', -selecttitles => 0, -selectmode => 'extended', -selecttype=>'row', -drawmode => 'slow', -scrollbars=>'e', -ipadx=>$MainTableIpadx, -padx=>$MainTablePadx, -pady=>12, -highlightthickness=>0 )->pack(-side=>'right', -expand => '1', -fill => 'both'); $MainTable->tagConfigure ("title", -bg => "$BackgroundTableHeader" +); $MainTable->tagConfigure ('leftjustify', -anchor=>'w'); $MainTable->tagConfigure ('WhiteRow', -bg => 'white'); $MainTable->tagConfigure ('ColoredRow', -bg => $BackgroundTableRow +); $MainTable->colWidth(0=> -100, 1=> -200, 2=> -200); $arrayVar->{"0,0"} = "Id"; $arrayVar->{"0,1"} = "Header 1"; $arrayVar->{"0,2"} = "Header 2"; $MainTable->configure(-font =>$GuiFontData); return $MainTable; } sub createTableRows{ my ($MainTable, $NumberRows) = @_; $MainTable->configure (-state=>'normal'); print "Creating rows in table (rows: $NumberRows)... "; $MainTable->insertRows(1, $NumberRows); $MainTable->configure (-state=>'disabled'); print "Done!\n"; } sub printData{ my ($MainTable, $NumberRows) = @_; my $IndexRow=1; #looping x times to simulate data, normally data is of different l +enghts. foreach (1..$NumberRows) { $arrayVar->{"$IndexRow,0"} = $IndexRow; foreach (1..2) { $arrayVar->{"$IndexRow,$_"} = "This is my text to be inser +ted This is my text to be inserted"; } setHeight($MainTable, $IndexRow); formattingTableRow($MainTable, $IndexRow); $IndexRow++; } $MainTable->tagRow('leftjustify',1..$NumberRows); } sub formattingTableRow{ my ($MainTable, $IndexRow)=@_; my $is_even = $IndexRow % 2 == 0; foreach (0..2){ if ($is_even == 0) { $MainTable->tagCell('WhiteRow',"$IndexRow,$_"); } else { $MainTable->tagCell('ColoredRow',"$IndexRow,$_"); } } } sub setHeight { my ($MainTable, $IndexRow) = @_; foreach my $cell (0..2) { $MainTable->activate("$IndexRow,$cell"); my $text = $MainTable->get('active'); my $font = $MainTable->Font (); my $widthdata = $MainTable->fontMeasure ($font, $text); my $widthcell = -(($MainTable->colWidth($cell))+($MainTableIpa +dx*2)+($MainTablePadx*2)+22); my $reqheight = int($widthdata / $widthcell) + 1; my $currheight = $MainTable->rowHeight($IndexRow); $MainTable->rowHeight($IndexRow, $reqheight) if ( ($cell == 0) + or ($reqheight > $currheight)); } }

Replies are listed 'Best First'.
Re: Tk TableMatrix automatic rowheight speed problem
by Takamoto (Monk) on Feb 11, 2019 at 10:10 UTC

    Hello

    You could:

    • Take out of the loop $font = $MainTable->Font (); and put it in the main part of the script after table has been created
    • Do not measure/adapt the first column (Id) as this width can be fix

    After applying these changes, the loading time is reduced of about 2/3. Still not ideal, but acceptable.

Re: Tk TableMatrix automatic rowheight speed problem
by swl (Prior) on Feb 11, 2019 at 22:34 UTC

    Did you use a profiler like Devel::NYTProf to identify the bottleneck?

    If not then it is worth doing as the standard output gives line by line timings which will pinpoint where most of the work is being done within each sub (how many times each line is called, how much time is spent on each line, etc.).

    I've used Devel::NYTProf to analyse a Gtk2 GUI to good effect.