2010-09-07 64 views
6

似乎CPAN上的一些(許多?)模塊部分使用XS在C中實現,並且如果需要可以回退到純粹的perl實現。雖然這很聰明,但它顯然會損害性能,我想知道它發生了,所以我可以解決這個問題。停止Perl XS模塊無聲地回退到pure-perl

是否有停止或檢測這種類型的回退的一般方法?

對於此行爲的例子來看看的(很方便)Date::Simplecode snippet

+1

我已經回答了通用的方法,但作爲一種'DateTime'是表示日期的事實上的perl發行版。 – 2010-09-07 14:46:27

+1

@Evan Carroll,DateTime可能是最流行的(也是功能完備的),但它並不是人們唯一使用的。有很多Perl日期模塊。 – cjm 2010-09-07 17:18:59

回答

6

的任何解決方案必須以每個模塊爲基礎(因爲決定哪些方案中使用由製造父模塊本身,而不是Perl中的一些機制)。在你引用的情況下,在使用語句後檢查$ Date :: Simple :: NoXs的值會告訴你是否正在使用XS。

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

例如,如果標量::的Util使用你必須檢查的dualvar功能存在的XS或純Perl的版本檢測。

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

那麼'Scalar :: Util'是如何告訴XS是否加載失敗,但我認爲你最好從外面檢查'@Scalar :: Util :: EXPORT_FAIL',它的'Scalar :: Util '明確地試圖爲你設置​​。 – 2010-09-07 14:53:46

+0

由於純Perl版本應該仍然有效,所以'warn'而不是'die'可能會更好,它只是慢一點。 – cjm 2010-09-07 17:17:04

5

這是一個很好的功能請求。不幸的是,對於模塊作者編程的內容,perl不知道模塊是否具有XS或純Perl(PP)變體以及引擎是否通過後備加載。

你提出的這個例子是由於它們打包在同一個發行版和模塊中,並且它們都在內部完成。我會補丁它遵循CPAN約定:DateSimple,這需要DateSimple::PP和推薦DateSimple::XS。這是如何Text::CSV,和其他人這樣做。此方法允許直接使用::XS構造函數強制使用XS,同時甚至不安裝pureperl變體。或者,您可以將它們打包在一起 - 這是Template::Stash用於Template::Stash::XS。讓任何事情統一起來的第一步是獲得特別的功能。

這樣的事情可能,如果模塊都在一個Moose::Role所提供的一些基本屬性_xs_class_name_pp_class_name,並engine_override拉輕鬆完成。但是,現在還沒有任何東西能夠實現這一目標,甚至可以用統一的API來實現這一目標。

+0

*爲* :: XS * :: PP信息..不能解決我的問題atm。雖然 – 2010-09-08 08:40:29

1

有一種通用的方法來檢測您的功能是XSUB簡歷。 只需檢查CV的XSUB插槽是否返回非NULL指針。

例如檢查我的:: func

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