fireartist has asked for the wisdom of the Perl Monks concerning the following question:
I've not attempted to use Inline::C since my last flirt, 3 years ago (Inline::C - object accessor failure) and my C knowledge is still almost non-existent.
However, I've got some methods which are called hundreds of thousands of times, and I'm trying to get the runtime down - and I'm hoping someone will offer to translate this particular one into Inline::C for me, so I can see if it makes a difference.
I've tried lots of variations of dealing with the SV** returned by hv_fetch() - but to be honest, I don't have a clue what I'm doing!
Here's the original perl method:
(btw - in the c-code, it would be sufficient to just check exists $self->{parent} rather than defined)
sub root {
my $self = shift;
while ( defined ( my $parent = $self->{parent} ) ) {
$self = $parent;
}
return $self;
}
Re: Inline::C hash access
by jettero (Monsignor) on Sep 04, 2008 at 11:55 UTC
|
For the method shown here, I doubt it would make much difference, and if it did, it'd probably be to slow it down rather than speed it up. If you're going to write things in C to speed them up, then it helps to have the data in C structures and access it there. Otherwise you might as well just use perl instead of introducing additional access layers.
Still, I could be wrong since the slowest part of perl is calling a sub. If you called your C function the hundreds of thousands of times from the C code (rather than from perl), it could possibly speed it up.
UPDATE: also, I've completed my assignment. I hope I get an A on my homework. (In all seriousness, I've never tried Inline::C before. Normally I don't write complete solutions...)
| [reply] [d/l] |
|
Thanks for this!
I initially tried renaming the c function to "form", which is the real name I'm using - but got an error about a previous declaration of Perl_form, so it looks like the functions are being put in a global namespace - however that's not a real problem - I just named it back to "root", then added a *form = \&root and it worked fine.
I found while trying to run my test suite, that the if( SvOK(sv) && SvTYPE(sv) == SVt_RV ) { } check was failing sometimes - I'm not sure why, so I'll have to investigate further. However, if I comment-out that check, all tests pass ok.
Running my usual profiling script shows the Inline::C version only runs about 2-3% faster (for total script runtime) - however, I think I'll be able to modify your code to replace a few other often-used methods - so hopefully, eventually, I'll be able to significantly speed up my program. - Thanks once again!
| [reply] [d/l] [select] |
|
if( SvOK(sv) && SvTYPE(sv) == SVt_RV )
That's not what you want - the SvTYPE just says what the SV's body physically consists of, and says nothing about whether it currently contains a valid RV. For example, if you do
$x = "foo"; $x = \$y; then the SvTYPE of $x is actually SVt_PV. You probably want:
if (SvROK(sv)) ...
Dave. | [reply] [d/l] [select] |
|
| [reply] |
Re: Inline::C hash access
by betterworld (Curate) on Sep 04, 2008 at 12:03 UTC
|
Have you considered storing the root directly, i.e. as $self->{root}?
Of course, this will only work if the parents don't change over time.
| [reply] [d/l] |
|
| [reply] [d/l] |
|
| [reply] |
|
| [reply] [d/l] |
|
|
|