所以我想提出一点鼠标速度的到我的其他子程序和做一些类型检查的点菜的数据类型检查
sub mysub {
my ($self, $int) = @_;
assert_int($int, 'int[1]');
}
子程序参数的Perl框架断言&的数据此数据的可选名称。这样我们会得到一个更有用的错误消息,例如
Assertion error! 'int[1]' is not an integer; got 'HASH(0xXXXXXXXXX)'
写它纯Perl不难。当您将gfx的其他模块Data :: Util的速度与Mouse &的速度进行比较时,显然纯XS解决方案具有优势,但缺少此可选参数名称。围绕Data :: Util的检查函数写一个小包装仍然比直接使用XS要慢。
有谁知道一套快速数据类型断言实用程序,允许将该字段名称传递给断言?
编辑 @ikegami回答了关于如何使用鼠标的类型系统的问题,似乎与仅使用XS库相比仍然缺乏性能。所以这个问题变得更多是否有一个基于XS的框架可以提供可定制的错误消息,或者至少让你说出什么属性被称为。
编辑这是我目前比较性能的代码。这已经基于gfx在Data::Util
和Mouse
的XS模式上的大量工作。这给了我们5倍的纯Perl解决方案的速度。将C与Perl进行比较是有点不公平的,这就是为什么我想知道一个框架是否已经存在,它可以提供这种性能,但却有正确的错误信息。我不想写这个东西,如果别人已经这样做:)
use Inline C => <<'END_C';
static int S_nv_is_integer(pTHX_ NV const nv) {
if(nv == (NV)(IV)nv){
return TRUE;
}
else {
char buf[64]; /* Must fit sprintf/Gconvert of longest NV */
const char* p;
(void)Gconvert(nv, NV_DIG, 0, buf);
p = &buf[0];
/* -?[0-9]+ */
if(*p == '-') p++;
while(*p){
if(!isDIGIT(*p)){
return FALSE;
}
p++;
}
return TRUE;
}
}
int assert_int(SV* sv, char* attributeName) {
assert(sv);
int result;
if(SvPOKp(sv)){
int const num_type = grok_number(SvPVX(sv), SvCUR(sv), NULL);
result = num_type && !(num_type & IS_NUMBER_NOT_INT);
}
else if(SvIOKp(sv)){
result = TRUE;
}
else if(SvNOKp(sv)) {
result = S_nv_is_integer(aTHX_ SvNVX(sv));
}
else {
result = FALSE;
}
if(! result) {
croak("'%s' was not an integer; got '%s'", attributeName, SvPV(sv, PL_na));
}
return result;
}
END_C
感谢有关如何访问鼠标类型约束的信息,我根本没有在文档中看到该方法。现在感觉很愚蠢:)。我使用鼠标重新运行我的基准测试,它的性能看起来比普通的Perl版本要低。所以这个问题现在稍微改变一下,基于XS的框架允许定制错误消息而没有巨大的损失。 – andeyatz
@andeyatz,也许你没有看错课程?约束条件是一个Mouse :: Meta :: Constraint – ikegami
@andeyatz,我很困惑,你说鼠标够快。什么改变了? – ikegami