Re: strict refs on / off process time
by robartes (Priest) on Nov 18, 2002 at 22:58 UTC
|
Hi shemp,
Could it not be easier to cure the disease instead of camouflaging the symptoms? I don't know how much of a redesign of your code this would take, but why not work with anonymous functions and real references instead of symbolic references? E.g.:
use strict;
my $funcref=sub {
print "My camel is shopping for flea deterrent.\n";
};
&$funcref;
# Note absence of no strict 'refs'
This way, there's no need to bounce up and down on the no strict 'refs'.
CU Robartes- | [reply] [d/l] |
|
|
I'm not sure this will work in my situation.
(Im not sure it wont either)
I'm no namespace / symbol table expert!
Anyway, here is what i'm doing. Im writing an engine for database migration / normalization. Our company receives data from about 100 (and growing) different sources, each providing data in different formats.
The subroutines that are being called within the strict / no strict, are functions to change the format of individual fields from the raw source -> our common database. For example, addresses need to be parsed into street name, number, direction, bulding, unit, city, state, zip, etc. And since this info comes from so many different sources with wildly varying formats for just that field, I have a variety of parsing functions. So, im having the engine call main::address_parser_73(...) as necessary.
(of course i'd never name a function address_parser_73).
So, i don't see a good way to do the above on the fly for using one of hundreds of potential functions.
But, as i said, i haven't done this sort of thing much - Im totally open to ideas.
thanks
| [reply] |
|
|
use strict;
my @parsers;
push @parsers, \&parser1; # Create a reference to parser 1 and push it
+ onto the array
push @parsers, \&parser2; # Ditto for parser 2
...
sub parser1 { parse..parse..parse };
sub parser2 { parse_somewhat_differently };
When a record from a source, say source 2 comes in, you access it's parser with:
$parsers[$source_id]->( arguments ); # $source_id contains the source,
+ e.g. 2
I have a feeling that you can even automate the process of creating the @parsers array by playing symbol table games, but I'm not awake enough any more to take a decent shot at it. Perhaps some more experienced (and awake) monk will step in here.
CU Robartes- | [reply] [d/l] [select] |
|
|
Store subrefs in a hash instead.
my %parsers = (
address => sub {
# ...
},
f_dcompany => sub {
# ...
},
xmlbzzwrd => sub {
# ...
},
);
Then you can call these like chromatic pointed out:
$parser{$whatever}->(@pass, $some, @params);
Makeshifts last the longest. | [reply] [d/l] [select] |
Re: strict refs on / off process time
by Elian (Parson) on Nov 19, 2002 at 01:38 UTC
|
Strict is a compile-time thing. You only pay once each time you turn it on or off, and it sets flag bits on the op nodes in the optree. There's no runtime penalty as such.
OTOH, I think you probably ought not do it. Use real sub refs, and if you need symbolic lookups, look them up in a hash that you've previously populated. There's more and better error checking that way. | [reply] |
|
|
How so? For the vars and subs strictures that is certainly true, but refs can only be checked at runtime to see if they're hard or symbolic.
Update: thanks.
Makeshifts last the longest.
| [reply] |
|
|
Sure, but that checking time is a constant, since regardless of your strict setting perl still needs to know what kind of data is in the scalar. Strictness only determines what perl does after the type is determined.
Besides, as I said, turning stricture on and off has no runtime penalty, since nothing is done at runtime to turn it on and off. Each op has a set of flags in it that determine a number of behaviors, including stricture. Turning strict on and off just determines, at compile time, what bits get set for the ops that are generated by the compiler. When those ops are actually run the strict setting is embedded inside the ops along with all the other flags.
| [reply] |
Re: strict refs on / off process time
by chromatic (Archbishop) on Nov 18, 2002 at 23:44 UTC
|
Unless you're in a very tight loops, this is negligible. Of course, I think resolving a symbolic reference is more expensive than calling a sub ref in a hash:
use strict;
my $func_name = "blah";
$functions{ $func_name }->( ... );
You can keep strict on, and Perl doesn't have to search the current symbol table to find an appropriate CV -- it's three or four ops shorter. (Somehow, I think your parser probably eats up more cycles.)
| [reply] [d/l] |
Re: strict refs on / off process time
by nothingmuch (Priest) on Nov 18, 2002 at 22:47 UTC
|
Since there is a subroutine call there is some overhead in making the change. However, the subroutine itself only changes some bits in $^H, so it's not a difficult call. If you can wrap the no strict 'refs' around a larger lexical scope you may benefit (such as around a loop). Perhaps you can make sure you don't use anything but hard refs except for that part, and keep it strict 'refs' on until you finally ship it the script. It'll probably be strict happy, but there is some risk involved. I wouldn't worry much though.
-nuffin zz zZ Z Z #!perl | [reply] |
|
|
Taking the strict / no strict up some loop level(s) is what i've done in the past, and since my current project is in-house only, i think i'll do the same, in that while debugging, i'll keep strict in the innermost loop, then pull it up some level(s) for speed.
thanks, all
| [reply] |
Re: strict refs on / off process time
by diotalevi (Canon) on Nov 18, 2002 at 22:54 UTC
|
You know, did you benchmark this first? I mean heck, we're talking about two piddly subroutine calls here (once to unset strict refs, once to set it again). There are probably better things to optimize than this.
__SIG__
use B;
printf "You are here %08x\n", unpack "L!", unpack "P4", pack
"L!", B::svref_2object(sub{})->OUTSIDE;
| [reply] [d/l] |
Re: strict refs on / off process time
by waswas-fng (Curate) on Nov 18, 2002 at 22:47 UTC
|
Why not try to take the no strict/strict block outside of the tight loop.
no strict 'refs';
while (true) {
&$func_name(...);
}
use strict;
vs
while (true){
no strict 'refs';
&$func_name(...);
use strict;
}
-Waswas
| [reply] [d/l] |