阻止Perl XS模块无声地回退到纯perl

时间:2010-09-07 14:29:37

标签: perl module cpan perl-module xs

CPAN上的一些(很多?)模块似乎部分使用XS在C中实现,如果需要,可以回退到纯perl实现。虽然这很聪明,但它显然会损害性能,我想知道它发生了,所以我可以解决问题。

是否有停止或检测此类后备的一般方法?

有关此行为的示例,请查看(非常方便)Date::Simplecode snippet

3 个答案:

答案 0 :(得分:6)

任何解决方案都必须基于每个模块(因为决定使用哪个实现由父模块本身,而不是Perl中的某些机制)。在您引用的情况下,在use语句之后检查$ Date :: Simple :: NoXs的值将告诉您是否正在使用XS。

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

例如,要检测Scalar :: Util是否使用XS或纯Perl版本,您必须检查是否存在双变量函数。

use Scalar::Util;
die "not using XS for Scalar::Util\n" unless if @Scalar::Util::EXPORTFAIL;

答案 1 :(得分:5)

这是一个非常好的功能请求。不幸的是,如果模块作者没有编写程序,perl不知道该模块是否具有XS或Pure Perl(PP)变体,以及引擎是否通过后备加载。

你提出的这个例子是因为它们被打包在同一个发行版和模块中,并且它都是在内部完成的。我会修补它以遵循CPAN惯例:DateSimple,这需要DateSimple::PP并建议DateSimple::XS。这就是Text::CSV和其他人的做法。此方法允许直接使用::XS构造函数强制使用XS,同时甚至不安装pureperl变体。或者,您可以将它们打包在一起 - 这是Template::StashTemplate::Stash::XS的处理方式。实现统一的第一步是获取特定功能。

如果所有模块都在Moose::Role中提供了一些基本属性_xs_class_name_pp_class_nameengine_override,则可以轻松完成此类操作。但是,再一次,到目前为止,甚至没有任何内容可以实现统一的API来实现这一目标。

答案 2 :(得分:1)

通常有一种方法可以检测到您的函数是XSUB CV。 只需检查CV的XSUB插槽是否返回非NULL指针。

e.g。检查My :: func

sub isxsub {
    use B;
    my $name = shift;
    my $cv = B::svref_2object(\&$name);
    return !!$cv->XSUB;
}