Perl 为什么substr左值比四个参数substr快?

Perl 为什么substr左值比四个参数substr快?,perl,substr,microbenchmark,Perl,Substr,Microbenchmark,从中,我们对这两种变体进行了基准测试 substr( $foo, 0, 0 ) = "Hello "; substr( $foo, 0, 0, "Hello " ); 在其中,我们发现substr-左值更快。池上说, 4-arg substr如何比左值substr慢(左值substr必须创建一个神奇的标量,并且需要额外的操作) 说实话,我也认为它会慢很多,只是因为它是由别人提出来的。纯粹出于好奇 在上述用例中,为什么substr-左值比四个argsubstr快?这只是一个糟糕的基准测试结果 当

从中,我们对这两种变体进行了基准测试

substr( $foo, 0, 0 ) = "Hello ";
substr( $foo, 0, 0, "Hello " );
在其中,我们发现
substr
-左值更快。池上说,

4-arg substr如何比左值substr慢(左值substr必须创建一个神奇的标量,并且需要额外的操作)

说实话,我也认为它会慢很多,只是因为它是由别人提出来的。纯粹出于好奇


在上述用例中,为什么
substr
-左值比四个arg
substr
快?

这只是一个糟糕的基准测试结果

当我复制您的结果时,我正在Windows Susbystem for Linux上使用perl进行解压。让我们只说性能对系统上的外部因素很敏感

即使在同一台计算机上使用Windows本机版本(草莓Perl),结果也会有很大的不同:

Rate substr substr\u valuete multicncat
速率子值子值子值多值
次级价值6997958/s--0%-27%
substr 7007667/s 0%--26%
Multincat 9533733/s 36%36%--
速率子值子值多ncat
substr 6795650/s--0%-10%
子价值6805545/s 0%--10%
Multincat 7526593/s 11%11%--
速率子值子值多ncat
substr 7513339/s--22%-28%
次级价值9693997/s 29%--6%
Multincat 10367639/s 38%7%--
速率子载波多载波子载波值
substr 8791152/s--13%-14%
Multincat 10139954/s 15%--1%
次级价值10240638/s 16%1%--
时间很短,机器太忙,无法获得准确的读数

(有一点是关于微观优化的…)

我讨厌在我的共享LinuxWeb主机上运行基准测试,但它通常会产生更加一致的结果。今天也不例外

Rate substr substr\u valuete multicncat
substr 4293130/s--3%-13%
次级价值4407446/s 3%--11%
Multincat 4938717/s 15%12%--
速率子值子值子值多值
次级价值4289732/s--2%-16%
substr 4356113/s 2%--15%
multiconcat 5096889/s 19%17%--
(我使用了
-3
而不是
100\u 000\u 000

所有差异均为3%或更少,这并不显著。就我所知,一个并不比另一个慢

事实上,人们不应该期望有任何不同。正如戴夫·米切尔所指出的,
substr($foo,0,0)=“你好”
被优化为几乎等同于substr($foo,0,0,“Hello”)自5.16起(在5.20中有所改进)

$perl-MO=简明,-exec-e'substr($foo,0,0,“Hello”);'
1进入
2下一状态(主1-e:1)v:{
3 gvsv[*foo]s
4常数[IV 0]s
5常数[IV 0]s
6常量[PV“你好”]s
7 substr[t2]vK/4
8离开[1参考]vKP/REFC
-e语法正常
$perl-MO=简明,-exec-e'substr($foo,0,0)=“你好”;'
1进入
2下一状态(主1-e:1)v:{
3常量[PV“你好”]s
4 gvsv[*foo]s
5常数[IV 0]s
6常数[IV 0]s
7 substr[t2]vKS/REPL1ST,3
8离开[1参考]vKP/REFC
-e语法正常

(唯一的区别是操作数的传递顺序,这是使用
REPL1ST
标志发出的信号。)

自5.16.0以来,左值+赋值变量已优化为4-arg变量(尽管在5.20.0之前,被置零的NOOP赋值op仍在执行路径中,这稍微减慢了它的速度).

和。后者是在分配给魔法标量后调用的。是的,对于我来说,即使使用-3,我对debian和Buster也会有巨大的不同。-3对100_000_000除了它运行的时间(3秒对100_000_000测试)没有任何区别对我来说,substr_左值与Multincat的时间差不多,并且总是比Intel(R)Core(TM)上的substr快i7-3520M CPU@2.90GHZ我们说的是每次交互大约100纳秒的时间,包括一个相对昂贵的子调用。这并不奇怪它会受到波动的影响。当测试这样的东西时,我使用
b_multicncat=>'使用严格;使用警告;对于(1..1000){my$foo=“world!”$foo=“Hello$foo”}“
@ikegami只是想知道,您使用了什么命令来获取这些结果数据?