http://qs321.pair.com?node_id=907592

ZJ.Mike.2009 has asked for the wisdom of the Perl Monks concerning the following question:

I wrote two very simple scripts, one in wxPerl, the other in Win32::GUI as will be shown below. They basically do the same thing, i.e. open a fairly large text file (30MB), takes the query input from the textbox, search the text file using the query and display relevant results if any in another textbox. I've noticed the wxPerl version is generally much slower (about 7 seconds or more) than the Win32-GUI version.

I'm wondering if this is just normal (I'm not sure if the problem is reproducible but I think so) or if something can be done to improve the speed of the wxPerl version.

==Win32-GUI version==

use strict; use warnings; use Win32::GUI(); my $window = new Win32::GUI::DialogBox( -width => 520, -height => 580, ); $window->Show(); my $entry = $window->AddTextfield( -size => [440,25], ); $entry->SetFocus; my $button = $window->AddButton( -name => 'button', -text => 'Search', -left => 448, -size =>[60,25], -ok => 1, ); my $display_field = $window->AddTextfield( -top => 30, -size => [513,513], -vscroll => 1, -multiline => 1, ); Win32::GUI::Dialog; sub button_Click { my $now = time; my $file = "./data"; #text file about the size of 30 MB open my $data, '<', $file or die "Open failed: $!"; $display_field->SelectAll(); $display_field->Clear(); my $query = $entry->Text; while (<$data>) { $display_field->Append($_) if /$query/i; } $now = time - $now; my $time = sprintf("\r\nTotal running time: %02d:%02d:%02d\r\n", int( +$now / 3600), int(($now % 3600) / 60), int($now % 60)); $display_field->Append($time); }

==wxPerl version==

use strict; use warnings; use Wx qw(:everything); my ($window, $entry, $display_field); package MyApp; use base 'Wx::App'; use Wx qw(:everything); sub OnInit { $window = Wx::Frame->new( undef, -1, '', [0,0], [520,580], ); $entry = Wx::TextCtrl->new( $window, -1, "", [0, 0], [408,-1], ); my $button = Wx::Button->new( $window, -1, "Search", [428,0], ); $display_field = Wx::TextCtrl->new( $window, -1, "", [0, 30], [508,513], wxTE_MULTILINE, ); Wx::Event::EVT_BUTTON( $button, -1, \&button_click,); sub button_click { my $now = time; #text file encoded in GB2312 about the size of 30 MB... #containing English and Chinese characters my $file = "./data"; open my $data, '<', $file or die "Open failed: $!"; $display_field->Clear; $display_field->Update; my $query = $entry->GetValue(); while(<$data>){ if(/$query/i){ $display_field->AppendText($_); $window->Update; } } $now = time - $now; my $time = sprintf("\n\nTotal running time: %02d:%02d:%02d\n\n", int +($now / 3600), int(($now % 3600) / 60), int($now % 60)); $display_field->AppendText($time); } $window->Show; } MyApp->new->MainLoop;
Evironment: StrawberryPerl 5.10.1 WinXP SP3(Chinese Simplified) Intel Core 2 T5200 CPU 1G memory

UPDATE

Thanks to GrandFather and @Anonmous Monk, I'm beginning to suspect that it might also have something to do with character encoding. I just wrote a Tk version and it runs *about as fast* as the Win32::GUI version but the Chinese characters contained in the file are garbled. I'll keep the post updated. Thanks.

UPDATE2

Just wrote a simple Tk version. It runs about as fast as the Win32::GUI. I'm thinking maybe the problem I'm experiencing is somehow related to character encoding. The following is a Tk version.
use Tk; use strict; use warnings; my $window = MainWindow -> new(); $window->geometry("520x580"); my $entry_frame = $window -> Frame()->pack(-side => "top"); my $entry = $entry_frame -> Entry (-width => 53, ) -> pack(-side => 'l +eft'); $entry -> bind('<Return>'=> \&button_Click); $entry -> focus; my $button = $entry_frame -> Button (-text => "Search", -command => \& +button_Click ) -> pack (-side => 'right'); my $display_field = $window -> Scrolled("Text",-scrollbars => 'e', ) - +> pack(-side => 'top',-fill => 'y', -expand => 1); sub button_Click { my $now = time; my $file = "./data"; #text file about the size of 30 MB open my $data, '<', $file or die "Open failed: $!"; $display_field->delete('0.0','end'); my $query = $entry->get(); while (<$data>) { if(/$query/i){ $display_field->insert("end",$_); $window->update; } } $now = time - $now; my $time = sprintf("\n\nTotal running time: %02d:%02d:%02d\n\n +", int($now / 3600), int(($now % 3600) / 60), int($now % 60)); $display_field->insert('end',$time); } MainLoop;

Update3

Just found the Tk version runs about as fast as the Win32::GUI when all Chinese characters in the data file become garbled. And if I resave the data file as utf8 or use the following file open argument:
my $file = "./data"; #text file about the size of 30 MB open my $data, '<:encoding(euc-cn)', $file or die "Open failed: $! +";
, all the Chinese characters contained in the data file will display properly but at the same time the speed suffers significanly and the Tk version will run just as slow as the wxPerl version.

Conclusion (?)

Win32::GUI is faster than wxPerl in my case perhaps because the data file used in my case contains both English and Chinese characters and the Chinese characters get displayed much faster on screen when using the native API of a Chinese system.

Another Test

This time I deleted all Chinese characteres contained in the 30MB data file, and then I tried wxPerl, Win32::GUI and Tk versions again. The result is this:

Tk is about as fast as Win32::GUI

wxPerl is still slower than Win32::GUI. In my previous test, it was about 7-8 seconds slower, but now the gap narrows to 3-4 seconds.

Replies are listed 'Best First'.
Re: Why is wxPerl slower than Win32GUI?
by GrandFather (Saint) on Jun 01, 2011 at 10:05 UTC

    Win32::GUI is Windows specific and is a thin layer over the native Windows GUI code. wxPerl on the other hand is a cross-platform wrapper around whatever system it happens to be running on. That portability comes at a price due to multiple abstraction layers which cost in terms of performance.

    If you don't need portability and are happy with the API of Win32::GUI go for it. I have no experience of wxPerl, but Tk (another cross-platform GUI) provides a simpler API than Win32::GUI as well as being cross-platform, so may be attractive for that reason where performance is less critical (the same is likely true of wxPerl).

    True laziness is hard work
      Oh, that makes sense. Thanks GrandFather.
Re: Why is wxPerl slower than Win32GUI?
by Anonymous Monk on Jun 01, 2011 at 10:50 UTC
    wxWidgets is a slightly thicker wrapper for the native widget set, so it will be a little slower

    FWIW, on my machine, with perl -le " print 1 for 1 .. 10*1024  " >data, and adding this to both files

    my $ix = 0; while (<$data>) { if(/$query/i){ $ix++; $display_field->Append("$ix : $_") } } ... warn "$time ";
    I get 8 for wxPerl, 4 for Win32::GUI, but Win32::GUI stops updating after ~3456 lines, go figure
      Thank you Anonymous Monk for the testing.

      To deal with the buffer overflow in Win32::GUI, you might need to add something like this:

      #Deals with buffer overflow $display_field->SetLimitText(10000000);
        With that change, the difference is zero to one second.
Re: Why is wxPerl slower than Win32GUI?
by Anonymous Monk on Jun 02, 2011 at 00:05 UTC
    Win32::GUI is faster than wxPerl in my case perhaps because the data file used in my case contains both English and Chinese characters and the Chinese characters get displayed much faster on screen when using the native API of a Chinese system.

    Is your wxPerl built with unicode support?

    In my latest results, wxPerl is the fastest by a one to two seconds

    $ perl zj907592tk.pl Total running time: 00:00:07 at zj907592tk.pl line 64, <$data> line 7553. $ perl zj907592w32.pl Total running time: 00:00:08 at zj907592w32.pl line 64, <$data> line 7553. $ perl zj907592wx.pl Total running time: 00:00:06 at zj907592wx.pl line 70, <$data> line 7553. Total running time: 00:00:06 at zj907592wx.pl line 70, <$data> line 7553.
    The chinese I got from http://corpus.leeds.ac.uk/internet.html looks like gibberish on my us english laptop

      @Anonymous Monk, thanks for the testing. The result is very interesting but I'm wondering if wxPerl would be still the fastest when you also get the Chinese characters displayed properly.

      And yes, my wxPerl fully supports unicode. Is there a wxPerl version that does not support Unicode? The thing is this: Win32::GUI does not support Unicode (even though my system fully supports Chinese and Unicode, Chinese characters encoded in utf8 get garbled in my Win32::GUI app). Tk partially supports Unicode. It does not support Unicode characters outside the basic multilingual plane (if my Tk app contains unicode characters outside the BMP, Tk crashes with a codepoint too high warning). Fortunately, wxPerl is the one that fully supports Unicode.
        The result is very interesting but I'm wondering if wxPerl would be still the fastest when you also get the Chinese characters displayed properly.

        The speed difference is well within the margin for noise. The only reason I mentioned it, is because it has been consistent in my tests. I doubt having a chinese font would make a difference (not going to test).

        And yes, my wxPerl fully supports unicode. Is there a wxPerl version that does not support Unicode?

        wxWidgets unicode support is optional (wxUNICODE)

Re: Why is wxPerl slower than Win32GUI?
by vkon (Curate) on Jun 03, 2011 at 09:55 UTC
      few years later... is this what you all are still using? Or is there something else? Or is this all still solid?
        I use Tcl::Tk on a regular basis and really happy with this.
        After some 10+ years of usage of this approach - I understood that this is the perfect balance of simplicity and power for my GUIs.
        Nicer GUI libs often require more efforts during coding, so I haven't switched to these.

        often I use pure Tcl CPAN module instead of Tcl::Tk, because I rarely actually need that perl/Tk syntax,

        $int->call($widget,'method','submethod', -smth=>'val');
        is quite enough, so perl/Tk syntax is an overkill
        $widget->methodSubmethod(-smth=>'val');
        given that most my GUI code is separated already into some place...

        You can write to our mail list and we will answer all of your questions, tcltk at perl dot org, you're welcome :)