小编Eri*_*rom的帖子

随着Perl 6实现的成熟,我们可以期待什么性能提升?

每次我下载Rakudo Perl 6的新副本时,我都运行以下表达式,只是为了了解它当前的性能:

say [+] 1 .. 100000;
Run Code Online (Sandbox Code Playgroud)

并且速度一直在增加,但每次计算都有明显的延迟(几秒).作为比较,Perl 5(或其他解释语言)中的类似内容几乎立即返回:

use List::Util 'sum';

print sum(1 .. 100000), "\n";
Run Code Online (Sandbox Code Playgroud)

或者在Ruby中(也几乎是即时的):

(1 .. 100000).inject(0) {|sum,x| sum+x}
Run Code Online (Sandbox Code Playgroud)

将表达式重写为Perl6的loop速度大约是缩小范围的两倍,但对于简单的计算,它仍然是一个非常明显的延迟(超过一秒):

my $sum;
loop (my $x = 1; $x <= 100000; $x++) {$sum += $x}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,Perl6实现的哪些方面导致了这些性能问题?并且这应该随着时间的推移而改善,还是这个开销是Perl6使用的"一切都是对象"模型的不幸副作用?

最后,loop构造比[+]减速算子更快吗?我认为循环将导致更多的总操作而不是减少.

编辑:

我会接受这两个mortiz年代和hobbs'如果我能的回答.一切都是作为一个方法调用处理更直接地回答为什么[+]慢,所以一个人得到它.

perl performance rakudo perl6 raku

27
推荐指数
4
解决办法
2971
查看次数

如何在Perl中完全删除包?

你如何完全删除Perl中的包?这不仅意味着包变量,还意味着Perl更新以处理继承更改和其他事物的任何魔术表.

这个简单的测试:

use warnings; use strict;
use Test::LeakTrace;
use Symbol 'delete_package';

leaktrace {
   package test;
   our $x = 1;

   package main;
   delete_package 'test';
};
Run Code Online (Sandbox Code Playgroud)

得到以下输出:

leaked ARRAY(0x81c930)  from /lib/perl5/5.10.1/Symbol.pm line 166.
leaked HASH(0x827760)   from /lib/perl5/5.10.1/Symbol.pm line 166.
leaked SCALAR(0x821920) from /lib/perl5/5.10.1/Symbol.pm line 166.
Run Code Online (Sandbox Code Playgroud)

使用该-verbose标志来leaktrace显示我可以根据请求发布的数据屏幕.

如果将行our @ISA = 'main';添加到test包中,情况会变得更糟:

leaked ARRAY(0x81cd10) from so.pl line 32.
leaked SCALAR(0x81c930) from so.pl line 32.
leaked ARRAY(0x8219d0) from so.pl line 32.
leaked HASH(0x8219c0) from so.pl line 32. …
Run Code Online (Sandbox Code Playgroud)

perl memory-leaks package

27
推荐指数
1
解决办法
673
查看次数

如何测试何时将功能添加到Perl?

是否有任何类似于键盘的服务允许您在旧版本的perl上测试Perl构造?

理想情况下,您可以在其中输入表达式的系统,它将告诉您它将使用的最旧版本的perl.

当然可以使用CPANTS,但这似乎是滥用服务(如果只是为了使BackPan更大).可能需要几天/几周才能在旧版本上获得不错的测试覆盖率.

testing perl version

26
推荐指数
3
解决办法
502
查看次数

在Perl中,为什么`while(<HANDLE>){...}`构造没有本地化`$ _`?

Perl没有$_使用以下语法自动进行本地化的设计(或技术)原因是什么:

while (<HANDLE>) {...}
Run Code Online (Sandbox Code Playgroud)

哪个被重写为:

while (defined( $_ = <HANDLE> )) {...}
Run Code Online (Sandbox Code Playgroud)

所有隐式写入其它结构的$_以集中方式做到这一点(for/foreach,map,grep),但是while,必须明确定位变量:

local $_;
while (<HANDLE>) {...}
Run Code Online (Sandbox Code Playgroud)

我的猜测是它与在命令行开关的"Super-AWK"模式下使用Perl有关,但这可能是错误的.

因此,如果有人知道(或者更好地参与语言设计讨论),您能否与我们分享这种行为背后的原因?更具体地说,为什么允许值$_在循环之外保持被认为是重要的,尽管它可能导致的错误(我倾向于在S​​O和其他Perl代码中看到所有这些)?


如果从上面不清楚,$_必须进行本地化的原因while如下例所示:

sub read_handle {
    while (<HANDLE>) { ... }
}

for (1 .. 10) {
     print "$_: \n"; # works, prints a number from 1 .. 10
     read_handle;
     print "done with $_\n";  # does not work, prints the last line read from …
Run Code Online (Sandbox Code Playgroud)

perl language-design local while-loop

23
推荐指数
2
解决办法
589
查看次数

有多少种方法可以描述Perl 6中的Fibonacci序列?

我一直在研究在Perl 6中构造惰性列表的各种方法,我想收集描述Fibonacci序列的所有简洁方法.

我将从马萨克的期刊中的三个开始:

my @fibs := (0, 1, -> $a, $b { $a + $b } ... *);

my @fibs := (0, 1, { $^a + $^b } ... *);  

my @fibs := (0, 1, *+* ... *);
Run Code Online (Sandbox Code Playgroud)

我认为这样的东西也会起作用,但我认为我的语法有误:

my @fibs := (0, 1, (@fibs Z+ @fibs[1..*]));
Run Code Online (Sandbox Code Playgroud)

有什么东西急切(切片?)并导致Rakudo进入无限循环.它是Haskell定义的翻译:

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
Run Code Online (Sandbox Code Playgroud)

更新:

看起来像zipWith示例的问题是@fibs[1..*]切片.if tail定义为sub tail (@x) {my $i = 1; {@x[$i++]}...*}然后它正常工作.我很想知道为什么切片对任何熟悉Rakudo内部的人来说都不是懒惰的.

另一个不错的是:

my …
Run Code Online (Sandbox Code Playgroud)

perl fibonacci lazy-evaluation perl6 raku

21
推荐指数
1
解决办法
1259
查看次数

Perl 5.10+中词汇$ _的好,坏和丑

从Perl 5.10开始,现在可以在语义上或在构造中$_明确地对上下文变量进行范围限定.my $_;given / when

有没有人发现词汇的好用$_?它是否使任何构造更简单/更安全/更快?

如果情况变得更复杂呢?词法是否在$_您的代码中引入了任何错误?(因为写入的控制结构$_将使用词法版本,如果它在范围内,如果它包含任何子例程调用(由于动态范围的丢失),这可以改变代码的行为)

最后,我想构建一个清单,明确何时$_用作词汇,全局,或者根本不重要.


注意:由于perl5-5.24这些实验性特征不再是perl的一部分.

perl global lexical perl5.10

19
推荐指数
1
解决办法
831
查看次数

有没有办法在Perl中重载正则表达式绑定运算符`= ~`?

我正在研究一个小型DSL,它使用nomethod回退进行重载来捕获重载值上使用的运算符.这类似于文档中描述的符号计算器的功能overload.

这适用于标准比较运算符,但请考虑以下事项:

my $ret = $overloaded =~ /regex/;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,nomethod调用stringify $overloaded,之后失去重载.我想要返回一个绑定变量,这至少会让我随身携带原始的重载对象,但在执行正则表达式时仍会丢失.

所以,最终的问题是,如果有什么办法可以延长overload的一个象征性的计算器的主意,包括正则表达式结合运营商=~!~,使上面的代码示例将调用nomethod($overloaded, qr/regex/, 0, '=~')或类似的东西?

我还简要介绍了重载smartmatch运算符,~~但似乎也没有做到这一点(总是默认为正则表达式匹配而不是重载).

编辑:我调查了~~更多,并发现my $ret = $overloaded ~~ q/regex/由于智能匹配规则的作用.关闭,但不是一个理想的解决方案,我希望它在5.10之前工作,所以我欢迎其他答案.

regex perl overloading operator-overloading

18
推荐指数
1
解决办法
552
查看次数

如何在Perl中实现数组?

Perl数组是一种抽象数据类型.Perl数组的内部机制是什么?它是用动态数组还是链表实现的?由于数组元素具有随机访问权限,因此我假设一个动态的指针数组,或者对标量的引用是有意义的.但是,对于数组头部的移位和非移位操作,数组是否必须通过这些操作移动其所有元素?听起来对我来说效率低下.任何想法?

perl language-implementation data-structures

17
推荐指数
2
解决办法
1925
查看次数

什么是有效的Perl模块返回值?

Perl中的常见做法当然是结束模块,1;以便可以检查对require的调用是否成功.有没有理由说返回值不是另一个真正的价值?在我的测试中,它不会导致任何问题,但我想知道是否有人遇到任何问题(例如一些其他模块或编译指示或任何期望值实际上1而不仅仅是真实的东西).

编辑:通过流行的观点,因为它只会工作一次(好的提示),代码示例消失了.似乎共识是它可以安全地返回任何真值,但从不依赖于调用代码中的那个值,因为它require1在第一次加载后返回

perl module

16
推荐指数
4
解决办法
5124
查看次数

这是Perl的glob原型的错误吗?

没有特别的原因,我正在使用glob原型(*),看看当参数是一个已定义的子程序时它会做什么.

给出以下代码:

sub test (*) {print "[@_]\n"}
sub blah ($) {"blah got @_"}
Run Code Online (Sandbox Code Playgroud)

如果你写,test blah;你会得到语法错误Not enough arguments for main::blah...

如果你编写test blah 1;程序编译并打印[blah]

如果你编写test blah die;程序编译,打印[blah]并且不会死.

如果你编写test blah(1);程序编译并打印[blah got 1]

如果你编写test blah(die);程序编译然后死亡.

最后两个例子显然是"如果它看起来像一个子程序调用它是一个子程序调用"规则的应用.

但是,没有括号的例子对我来说似乎是个错误.因为似乎正在发生的事情是,尽管处于glob上下文中,解析器仍然将其blah视为需要参数的原型函数.但是当编译完成后,参数将blah被完全抛弃,而字符串'blah'则被传递给test.

以下是test blah die;构造运行的示例B::Deparse:

$ perl -MO=Deparse,-p -e 'sub test (*) {print "[@_]\n"} sub blah ($) {"blah got @_"} …
Run Code Online (Sandbox Code Playgroud)

syntax perl prototype

16
推荐指数
1
解决办法
459
查看次数