Остановка модулей Perl XS от тихого возврата к чистому Perl - PullRequest
6 голосов
/ 07 сентября 2010

Кажется, что некоторые (многие?) Модули в CPAN частично реализованы на C с использованием XS и могут при необходимости вернуться к реализации на чистом Perl. Несмотря на то, что это разумно, это, очевидно, может ухудшить производительность, и я хотел бы знать, что это происходит, чтобы решить проблему.

Существует ли общий способ остановки или обнаружения этого типа отступления?

Для примера такого поведения взгляните на (очень удобно) Date :: Simple ( фрагмент кода )

Ответы [ 3 ]

6 голосов
/ 07 сентября 2010

Любое решение должно приниматься для каждого модуля (поскольку решение о том, какую реализацию использовать, принимается самим родительским модулем, а не каким-либо механизмом в Perl). В случае, указанном вами, проверка значения $ Date :: Simple :: NoXs после оператора use покажет вам, используется ли 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;
5 голосов
/ 07 сентября 2010

Это действительно хороший запрос.К сожалению, если не считать того, что запрограммировал автор модуля, Perl не знает, есть ли у модуля варианты XS или Pure Perl (PP) и загружен ли двигатель из-за отказа.

Этот пример, который вы привели, составлен изэффект, что они упакованы в один и тот же дистрибутив и модуль, и все это делается изнутри.Я бы исправил его в соответствии с соглашением CPAN: DateSimple, которое требует DateSimple::PP и рекомендует DateSimple::XS.Вот как Text::CSV и другие это делают.Этот метод позволяет напрямую использовать конструктор ::XS для принудительного использования XS и в то же время даже не устанавливать вариант pureperl.Кроме того, вы можете упаковать их вместе - это то, что Template::Stash делает с Template::Stash::XS.Первый шаг к получению чего-либо унифицированного - это получение функциональности ad-hoc.

Подобного рода вещи можно было бы легко сделать, если бы все модули извлекали Moose::Role, который предоставлял несколько основных атрибутов _xs_class_name, _pp_class_name и engine_override.Но, опять же, на данный момент нет ничего, что могло бы даже создать единый API для достижения этой цели.

1 голос
/ 31 декабря 2010

Существует общий способ определить, что ваша функция - это XSUB CV. Просто проверьте, возвращает ли слот XSUB CV ненулевой указатель или нет.

например. проверить на My :: func

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