Skip Menu |

This queue is for tickets about the Wx CPAN distribution.

Report information
The Basics
Id: 58579
Status: open
Priority: 0/
Queue: Wx

People
Owner: Nobody in particular
Requestors: adamk [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Compile Wx constants without exporting Wx constants
A large Wx-based application will contains dozens or hundreds of classes that need to use Wx and the constants within it. Our experience from Padre suggests that the two main ways of consuming Wx constants don't scale. Firstly, you can suck in everything. use Wx ':everything'; This is just fine for a single class, but the sheer volume of symbols results in something like 50k of memory burnt. Multiply this by 20 classes and you end up with 1meg of RAM. Multiply it by 200 classes and you get 10meg of RAM, just to use the constants. The second and more efficient option is to name the specific symbols. use Wx qw{ wxDefaultPosition wxDefaultSize }; Unfortunately, this becomes highly unweildy at scale because of the heavy need for double maintenance and all the extra code that is required for no functional effect. The only effect all this import code has is to reduce the memory cost of accessing Wx constants. The problem is that you can't avoid doing this importing even if you want to. The following does not work. use Wx (); my $value = Wx::wxDefaultPosition; And yet this alternative DOES work... use Wx ':everything'; my $value = Wx::wxDefaultPosition; In Padre, we work around this problem by having one master class import everything and in the process "stimulate" all the Wx::wxFOO constants into existing. All other Padre classes can then use any Wx::wxFOO constant with impunity. This is both computationally efficient, and reads pretty cleanly in the code itself. I would love to see some kind of similar effect implemented in Wx core itself, perhaps via a ':compile' type option. This would save Padre from importing all those symbols into Padre::Wx, and would greatly simplify code generators producing Wx code, because they don't have to track and import each constant used. Perhaps it would just be better to declare all the constants full all the time, or to declare all the constants consumed by a class (say, Wx::Dialog) by default whenever each class that can use them are loaded. It feels like there should be some way of doing this better than what is done now...
CC: wxperl-users [...] perl.org, ADAMK [...] cpan.org
Subject: Re: [rt.cpan.org #58579] Compile Wx constants without exporting Wx constants
Date: Wed, 23 Jun 2010 16:38:14 +0200
To: bug-Wx [...] rt.cpan.org
From: Steffen Mueller <smueller [...] cpan.org>
Hi Adam, Adam Kennedy via RT wrote: Show quoted text
> Tue Jun 22 07:27:02 2010: Request 58579 was acted upon. > Subject: Compile Wx constants without exporting Wx constants
Show quoted text
> use Wx (); > > my $value = Wx::wxDefaultPosition;
Without saying anything about whether the following is good or not: The reason it works like this is that the constants are generated via AUTOLOAD. They are listed in Constant.xs. I wonder why Wx doesn't use ExtUtils::Constant to generate the constants (also using AUTOLOAD, usually). EU::Constant can generate code that is likely more efficient than the repeated call to strEQ. Is it because of the ifdefs on wxWidgets versions? Would it be worthwhile to patch EU::Constant to allow for this kind of conditional code generation? If we assumed somebody wanted all those constants anyway, we could generate the XSUBs at XS compile time. --Steffen
CC: wxperl-users [...] perl.org
Subject: Re: [rt.cpan.org #58579] Compile Wx constants without exporting Wx constants
Date: Wed, 23 Jun 2010 21:08:07 +0100
To: bug-Wx [...] rt.cpan.org
From: Mark Dootson <mark.dootson [...] znix.com>
I always found use Wx qw(:sizer :window :id :misc :listctrl); etc. provides just the right level of control for my needs. On 22/06/2010 12:27, Adam Kennedy via RT wrote: Show quoted text
> Tue Jun 22 07:27:02 2010: Request 58579 was acted upon. > Transaction: Ticket created by ADAMK > Queue: Wx > Subject: Compile Wx constants without exporting Wx constants > Broken in: (no value) > Severity: (no value) > Owner: Nobody > Requestors: adamk@cpan.org > Status: new > Ticket<URL: https://rt.cpan.org/Ticket/Display.html?id=58579> > > > A large Wx-based application will contains dozens or hundreds of classes > that need to use Wx and the constants within it. > > Our experience from Padre suggests that the two main ways of consuming > Wx constants don't scale. > > Firstly, you can suck in everything. > > use Wx ':everything'; > > This is just fine for a single class, but the sheer volume of symbols > results in something like 50k of memory burnt. > > Multiply this by 20 classes and you end up with 1meg of RAM. Multiply it > by 200 classes and you get 10meg of RAM, just to use the constants. > > The second and more efficient option is to name the specific symbols. > > use Wx qw{ > wxDefaultPosition > wxDefaultSize > }; > > Unfortunately, this becomes highly unweildy at scale because of the > heavy need for double maintenance and all the extra code that is > required for no functional effect. > > The only effect all this import code has is to reduce the memory cost of > accessing Wx constants. > > The problem is that you can't avoid doing this importing even if you > want to. > > The following does not work. > > use Wx (); > > my $value = Wx::wxDefaultPosition; > > And yet this alternative DOES work... > > use Wx ':everything'; > > my $value = Wx::wxDefaultPosition; > > In Padre, we work around this problem by having one master class import > everything and in the process "stimulate" all the Wx::wxFOO constants > into existing. > > All other Padre classes can then use any Wx::wxFOO constant with > impunity. This is both computationally efficient, and reads pretty > cleanly in the code itself. > > I would love to see some kind of similar effect implemented in Wx core > itself, perhaps via a ':compile' type option. > > This would save Padre from importing all those symbols into Padre::Wx, > and would greatly simplify code generators producing Wx code, because > they don't have to track and import each constant used. > > Perhaps it would just be better to declare all the constants full all > the time, or to declare all the constants consumed by a class (say, > Wx::Dialog) by default whenever each class that can use them are loaded. > > It feels like there should be some way of doing this better than what is > done now...
Il Mar 22 Giu 2010 07:27:02, ADAMK ha scritto: Show quoted text
> I would love to see some kind of similar effect implemented in Wx core > itself, perhaps via a ':compile' type option. > > This would save Padre from importing all those symbols into Padre::Wx, > and would greatly simplify code generators producing Wx code, because > they don't have to track and import each constant used. > > Perhaps it would just be better to declare all the constants full all > the time, or to declare all the constants consumed by a class (say, > Wx::Dialog) by default whenever each class that can use them are loaded.
Sadly, there isn't any delayed loading implemented yet. Show quoted text
> It feels like there should be some way of doing this better than what is > done now...
I suppose all you need is: m/^:some_meaningful_name$/ and do { require subs; subs->import( @EXPORT_OK ); }; in Wx::import? I tried it in an one-liner and it seems to do what you need. Regards, Mattia
Il Mer 23 Giu 2010 10:38:26, SMUELLER ha scritto: Show quoted text
> Hi Adam, > > Adam Kennedy via RT wrote:
> > Tue Jun 22 07:27:02 2010: Request 58579 was acted upon. > > Subject: Compile Wx constants without exporting Wx constants
>
> > use Wx (); > > > > my $value = Wx::wxDefaultPosition;
> > Without saying anything about whether the following is good or not: The > reason it works like this is that the constants are generated via > AUTOLOAD. They are listed in Constant.xs.
Not exactly; it's Exporter that declares them. AUTOLOAD is only invoked if the constant is actually used. Show quoted text
> I wonder why Wx doesn't use ExtUtils::Constant to generate the constants > (also using AUTOLOAD, usually).
At the time, I did not know about it. Show quoted text
> EU::Constant can generate code that is > likely more efficient than the repeated call to strEQ.
s/likely/surely/ :-) Show quoted text
> Is it because of > the ifdefs on wxWidgets versions?
That is one of the reasons I never switched to it. Show quoted text
>Would it be worthwhile to patch EU::Constant to allow for this kind of conditional code
generation? A speed increase can't hurt, and I don't think there will be a maintenance increase/decrease; I'm not sure the speed increase is going to be noticeable, though. Are there any benchmarks for ExtUtils::Constant? Show quoted text
> If we assumed somebody wanted all those constants anyway, we could > generate the XSUBs at XS compile time.
This has a better chance of actually speeding things up (because the subs will be visible at Perl compile time, and inlineable). Again, not sure it matters for most applications. Reagrds, Mattia P.S.: I'd welcome a patch implementing any of the two, it just isn't my itch
Subject: RE: [rt.cpan.org #58579] Compile Wx constants without exporting Wx constants
Date: Thu, 24 Jun 2010 10:57:19 -0700
To: <bug-Wx [...] rt.cpan.org>, <wxperl-users [...] perl.org>
From: "Jan Dubois" <jand [...] activestate.com>
On Tue, 22 Jun 2010, Adam Kennedy via RT wrote: [...] Show quoted text
> The problem is that you can't avoid doing this importing even if you > want to. > > The following does not work. > > use Wx (); > > my $value = Wx::wxDefaultPosition;
Yes, because Wx::wxDefaultPosition is just a bareword here, so it will be interpreted as a string literal if the function has not yet been defined. It should work correctly if you add parenthesis though: my $value = Wx::wxDefaultPosition(); Cheers, -Jan
CC: adamk [...] cpan.org
Subject: Re: [rt.cpan.org #58579] Compile Wx constants without exporting Wx constants
Date: Fri, 25 Jun 2010 13:48:25 +1000
To: bug-Wx [...] rt.cpan.org
From: Adam Kennedy <adamkennedybackup [...] gmail.com>
On 25 June 2010 03:57, jand@ActiveState.com via RT <bug-Wx@rt.cpan.org> wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=58579 > > > On Tue, 22 Jun 2010, Adam Kennedy via RT wrote: > [...]
>> The problem is that you can't avoid doing this importing even if you >> want to. >> >> The following does not work. >> >>   use Wx (); >> >>   my $value = Wx::wxDefaultPosition;
> > Yes, because Wx::wxDefaultPosition is just a bareword here, so it will > be interpreted as a string literal if the function has not yet been > defined. It should work correctly if you add parenthesis though: > >    my $value = Wx::wxDefaultPosition();
Of course you can do that, I just feel I shouldn't have to. There are currently 1,154 places in 94 files in just the core Padre code where we call a Wx constant. I would rather like to avoid needing 94 import declarations, or needing 2,308 parenthesis characters. And if the constants were all fast/inlined, that would be nice too. Adam K