阻止 Perl XS 模块默默地回退到纯 Perl

发布于 2024-09-18 00:35:56 字数 321 浏览 13 评论 0 原文

看起来 CPAN 上的一些(很多?)模块部分是使用 XS 在 C 中实现的,并且如果需要的话可以回退到纯 Perl 实现。虽然这很聪明,但它显然会损害性能,我想知道它是否发生,以便我可以解决问题。

是否有一种通用方法可以阻止或检测这种类型的后备?

有关此行为的示例,请查看(非常方便)Date::Simple (< a href="http://p3rl.org/8746IHPL" rel="nofollow noreferrer">代码片段)

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

双马尾 2024-09-25 00:35:56

任何解决方案都必须以每个模块为基础(因为使用哪个实现的决定是由父模块本身决定的,而不是 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 版本,您必须检查 Dualvar 函数是否存在。

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

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;
缪败 2024-09-25 00:35:56

这是一个非常好的功能请求。不幸的是,由于缺少模块作者所编写的内容,perl 不知道该模块是否具有 XS 或 Pure Perl (PP) 变体以及引擎是否通过回退加载。

您提出的这个示例由于它们被打包在同一发行版和模块中而变得更加复杂,并且这一切都是在内部完成的。我将对其进行修补以遵循 CPAN 约定:DateSimple,它需要 DateSimple::PP 并推荐 DateSimple::XS。这就是 Text::CSV,其他人也这样做。此方法允许直接使用 ::XS 构造函数来强制使用 XS,同时甚至不安装 pureperl 变体。或者,您可以将它们打包在一起 - 这就是 Template::Stash模板::Stash::XS。实现统一的第一步是获得临时功能。

如果所有模块都引入一个 Moose::Role 并提供一些基本属性 _xs_class_name_pp_class_name、和engine_override。但是,到目前为止,还没有任何东西可以提供统一的 API 来实现这一目标。

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.

_畞蕅 2024-09-25 00:35:56

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

例如检查 My::func

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

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文