为什么 substr-lvalue 比四参数 substr 快?
来自 这个问题,我们对这两个变体进行基准测试,
From this question, we benchmark these two variants,
substr( $foo, 0, 0 ) = "Hello ";
substr( $foo, 0, 0, "Hello " );
在其中我们发现 substr
-lvalue 更快.池上说,
In it we discover that substr
-lvalue is faster. To which Ikegami said,
4-arg substr 比左值 substr 慢(它必须创建一个神奇的标量,并且需要额外的操作)???– ikegami
How is 4-arg substr slower than lvalue substr (which must create a magical scalar, and requires extra operations)??? – ikegami
说实话,我也认为它会慢很多,只是提到它是因为它是由其他人提出的.纯粹出于好奇,
Truth be told, I also assumed that it would be massively slower and just mentioned it because it was brought up by someone else. Purely for curiosity,
为什么在上述用例中 substr
-lvalue 比四参数 substr
快?
Why is substr
-lvalue faster than four-arg substr
in the above usecase?
这只是一个糟糕的基准测试结果.
It was simply a bad benchmark result.
当我复制您的结果时,我在 Windows Susbsytem for Linux 上的 Unbuntu 上使用 perl.假设性能对该系统的外部因素很敏感.
When I replicated your results, I was using perl on Unbuntu on Windows Susbsytem for Linux. Let's just say that performance is sensitive to external factors on that system.
即使在同一台计算机上使用 Windows (Strawberry Perl) 的本机构建,结果也有很大差异:
Even when using a native build for Windows (Strawberry Perl) on the same computer, I get wild differences in the results:
Rate substr substr_valute multiconcat
Rate substr_valute substr multiconcat
substr_valute 6997958/s -- -0% -27%
substr 7007667/s 0% -- -26%
multiconcat 9533733/s 36% 36% --
Rate substr substr_valute multiconcat
substr 6795650/s -- -0% -10%
substr_valute 6805545/s 0% -- -10%
multiconcat 7526593/s 11% 11% --
Rate substr substr_valute multiconcat
substr 7513339/s -- -22% -28%
substr_valute 9693997/s 29% -- -6%
multiconcat 10367639/s 38% 7% --
Rate substr multiconcat substr_valute
substr 8791152/s -- -13% -14%
multiconcat 10139954/s 15% -- -1%
substr_valute 10240638/s 16% 1% --
时间太短,机器太忙而无法获得准确的读数.
The times are just so small, and the machine is just too busy to get accurate readings.
(有一点是关于微优化的……)
(There's a point to be made about micro-optimizations in there somewhere...)
我讨厌在我的共享 linux 网络主机上运行基准测试,但它通常会产生更一致的结果.今天也不例外.
I hate running benchmarks on my shared linux web host, but it normally produces far more consistent results. Today was no exception.
Rate substr substr_valute multiconcat
substr 4293130/s -- -3% -13%
substr_valute 4407446/s 3% -- -11%
multiconcat 4938717/s 15% 12% --
Rate substr_valute substr multiconcat
substr_valute 4289732/s -- -2% -16%
substr 4356113/s 2% -- -15%
multiconcat 5096889/s 19% 17% --
(我使用了 -3
而不是 100_000_000
.)
(I used -3
instead of 100_000_000
.)
所有差异均小于或等于 3%,这并不显着.据我所知,一个并不比另一个慢.
All differences are 3% or less, which isn't significant. As far as I can tell, one isn't slower than the other.
事实上,人们不应该期望有任何不同.正如 Dave Mitchell 所指出的,substr( $foo, 0, 0 ) = "Hello ";
被优化为几乎等同于 substr( $foo, 0, 0, "Hello ");
自 5.16 起(在 5.20 中有所改进).
In fact, one shouldn't expect any difference. As pointed out by Dave Mitchell, substr( $foo, 0, 0 ) = "Hello ";
is optimized into something virtually equivalent to substr( $foo, 0, 0, "Hello " );
since 5.16 (with an improvement in 5.20).
$ perl -MO=Concise,-exec -e'substr( $foo, 0, 0, "Hello " );'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <#> gvsv[*foo] s
4 <$> const[IV 0] s
5 <$> const[IV 0] s
6 <$> const[PV "Hello "] s
7 <@> substr[t2] vK/4
8 <@> leave[1 ref] vKP/REFC
-e syntax OK
$ perl -MO=Concise,-exec -e'substr( $foo, 0, 0 ) = "Hello ";'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <$> const[PV "Hello "] s
4 <#> gvsv[*foo] s
5 <$> const[IV 0] s
6 <$> const[IV 0] s
7 <@> substr[t2] vKS/REPL1ST,3
8 <@> leave[1 ref] vKP/REFC
-e syntax OK
(唯一的区别是操作数的传递顺序,使用 REPL1ST
标志发出信号.)
(The only difference is the order in which the operands are passed, which is signaled using the REPL1ST
flag.)