Stopping Perl XS modules from silently falling back to pure-perl
Asked Answered
H

3

6

It seems some (many?) modules on CPAN are partly implemented in C using XS, and can fall back to a pure-perl implementation if necessary. While this is smart, it can obviously hurt performance, and I would like to know it happens so I can fix the problem.

Is there a general way of stopping or detecting this type of fallback?

For an example of this behaviour take a look at the (very handy) Date::Simple (code snippet)

Huckleberry answered 7/9, 2010 at 14:29 Comment(2)
I've answered on the generic approach, but as an aside DateTime is the defacto perl distro for representing dates.Nerte
@Evan Carroll, DateTime may be the most popular (and feature-full), but it's hardly the only one people use. There are lots of Perl date modules.Appellative
K
6

Any solution would have to be on a per module basis (because the decision on which implementation to use is made by the parent module itself, not some mechanism in Perl). In the case you cited, checking the value of $Date::Simple::NoXs after the use statement will tell you if XS is being used or not.

use Date::Simple;
die "not using XS for Date::Simple\n" if $Date::Simple::NoXs;

For instance, to detect if Scalar::Util is using the XS or pure Perl versions you have to check for the existence of the dualvar function.

use Scalar::Util;
die "not using XS for Scalar::Util\n" unless if @Scalar::Util::EXPORTFAIL;
Kowal answered 7/9, 2010 at 14:40 Comment(2)
Well that's how Scalar::Util goes about telling if the XS failed to load, but I think you'd be better off from the outside checking @Scalar::Util::EXPORT_FAIL, which Scalar::Util explicitly tries to set up for you.Nerte
It would probably be better to warn rather than die, since the pure-Perl version should still work; it's just slower.Appellative
N
5

This is a really good feature request. Unfortunately, short of what the module author has programmed, perl has no knowledge if the module has XS or Pure Perl (PP) variants and if the engine was loaded through fallback.

This example you bring up is compounded by the effect that they're packaged in the same distro and module, and it is all done internally. I'd patch it to follow the CPAN convention: DateSimple, which requires DateSimple::PP and recommends DateSimple::XS. This is how Text::CSV, and others do it. This method permits using the ::XS constructor directly to force use of XS and at the same time not even installing the pureperl variant. Alternatively, you can package them together -- this is what Template::Stash does with Template::Stash::XS. The first step to getting anything unified is getting the functionality ad-hoc.

This sort of thing could be easily done if the modules all pulled in a Moose::Role that provided a few basic attributes _xs_class_name, _pp_class_name, and engine_override. But, again, there is nothing as of now that even seeds a unified API to achieve this.

Nerte answered 7/9, 2010 at 14:44 Comment(1)
+1 for the *::XS *::PP info.. doesn't solve my problem atm. thoughEscuage
D
1

There is a general way to detect that your function is a XSUB CV. Just check if the XSUB slot of the CV returns a non-NULL pointer or not.

e.g. check for My::func

sub isxsub {
    use B;
    my $name = shift;
    my $cv = B::svref_2object(\&$name);
    return !!$cv->XSUB;
}
Dowable answered 31/12, 2010 at 8:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.