2010-09-07 20 views
6

Có vẻ như một số (nhiều?) Mô-đun trên CPAN được thực hiện một phần trong C bằng cách sử dụng XS, và có thể rơi trở lại thực hiện tinh khiết perl nếu cần thiết. Trong khi điều này là thông minh, nó rõ ràng có thể làm tổn thương hiệu suất, và tôi muốn biết điều đó xảy ra để tôi có thể khắc phục vấn đề.Dừng mô-đun Perl XS từ im lặng rơi trở lại tinh khiết-perl

Có cách nào chung để dừng hoặc phát hiện loại dự phòng này không?

Đối với một ví dụ về hành vi này có một cái nhìn tại (rất tiện dụng) Date::Simple (code snippet)

+1

Tôi đã trả lời theo cách tiếp cận chung, nhưng như là một 'DateTime' sang một bên là bản phân phối peract defacto để biểu diễn ngày tháng. –

+1

@Evan Carroll, DateTime có thể là phổ biến nhất (và tính năng đầy đủ), nhưng nó hầu như không phải là người duy nhất sử dụng. Có rất nhiều mô-đun ngày Perl. – cjm

Trả lời

6

Bất kỳ giải pháp sẽ phải được trên một cơ sở cho mỗi mô-đun (vì quyết định mà thực hiện để sử dụng được thực hiện bởi chính mô-đun chính, không phải một số cơ chế trong Perl). Trong trường hợp bạn trích dẫn, kiểm tra giá trị của $ Date :: Simple :: NoXs sau khi sử dụng câu lệnh sẽ cho bạn biết XS có đang được sử dụng hay không.

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

Ví dụ: để phát hiện xem Scalar :: Util đang sử dụng XS hoặc phiên bản Perl tinh khiết, bạn phải kiểm tra sự tồn tại của hàm dualvar.

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

Vâng đó là cách 'Scalar :: Util' đi về nói nếu XS không tải được, nhưng tôi nghĩ bạn nên tốt hơn từ việc kiểm tra bên ngoài' @Scalar :: Util :: EXPORT_FAIL', mà 'Scalar :: Util 'cố gắng thiết lập cho bạn một cách rõ ràng. –

+0

Nó có thể sẽ tốt hơn để 'cảnh báo' thay vì' chết', vì phiên bản thuần túy Perl vẫn hoạt động; nó chỉ chậm hơn. – cjm

5

Đây là một yêu cầu tính năng thực sự tốt. Thật không may, ngắn của những gì tác giả mô-đun đã được lập trình, perl không có kiến ​​thức nếu các mô-đun có XS hoặc biến thể Perl tinh khiết (PP) và nếu động cơ đã được nạp thông qua dự phòng.

Ví dụ này bạn đưa ra được kết hợp bởi hiệu ứng mà chúng được đóng gói trong cùng một bản phân phối và mô-đun và tất cả được thực hiện trong nội bộ. Tôi muốn vá nó theo quy ước của CPAN: DateSimple, yêu cầu DateSimple::PP và đề xuất DateSimple::XS. Đây là cách Text::CSV và những người khác làm điều đó. Phương pháp này cho phép sử dụng phương thức khởi tạo ::XS trực tiếp để buộc sử dụng XS và đồng thời thậm chí không cài đặt biến thể pureperl. Ngoài ra, bạn có thể gói chúng lại với nhau - đây là những gì Template::Stash thực hiện với Template::Stash::XS. Bước đầu tiên để nhận được bất cứ điều gì thống nhất là nhận được chức năng ad-hoc.

Loại điều này có thể dễ dàng thực hiện nếu tất cả các mô-đun được lấy trong một Moose::Role cung cấp một số thuộc tính cơ bản _xs_class_name, _pp_class_nameengine_override. Nhưng, một lần nữa, không có gì bây giờ mà ngay cả hạt giống một API thống nhất để đạt được điều này.

+0

+1 cho * :: XS * :: Thông tin PP .. không giải quyết được vấn đề của tôi. Tuy nhiên –

1

Có một cách chung để phát hiện rằng chức năng của bạn là CV XSUB. Chỉ cần kiểm tra xem khe XSUB của CV có trả về con trỏ không NULL hay không.

ví dụ: kiểm tra My :: func

sub isxsub { 
    use B; 
    my $name = shift; 
    my $cv = B::svref_2object(\&$name); 
    return !!$cv->XSUB; 
} 
Các vấn đề liên quan