gpt4 book ai didi

perl - Perl 的 unpack() 比 substr() 快吗?

转载 作者:行者123 更新时间:2023-12-03 21:13:20 24 4
gpt4 key购买 nike

我读过好几次 unpack()substr() 快,尤其是随着子串数量的增加。但是,该基准表明并非如此。是我的基准测试有缺陷,还是 unpack() 所谓的性能优势?旧版本 Perl 的遗留物?

use strict;
use warnings;
use Benchmark;

my ($data, $format_string, $n_substrings);

my %methods = (
unpack => sub { return unpack $format_string, $data },
substr => sub { return map {substr $data, $_, 1} 0 .. $n_substrings - 1 },
);

for my $exp (1 .. 5){
$n_substrings = 10 ** $exp;
print $n_substrings, "\n";
$format_string = 'a1' x $n_substrings;
$data = 9 x $n_substrings;
Benchmark::cmpthese -2, \%methods;
}

输出(在 Windows 上):
10
Rate unpack substr
unpack 131588/s -- -52%
substr 276802/s 110% --
100
Rate unpack substr
unpack 13660/s -- -57%
substr 31636/s 132% --
1000
Rate unpack substr
unpack 1027/s -- -68%
substr 3166/s 208% --
10000
Rate unpack substr
unpack 84.4/s -- -74%
substr 322/s 281% --
100000
Rate unpack substr
unpack 5.46/s -- -82%
substr 30.1/s 452% --

正如一些答案所指出的, unpack()在 Windows 上表现不佳。这是在solaris 机器上的输出——不是那么决定性,而是 substr()仍然赢得竞跑:
10
Rate unpack substr
unpack 202274/s -- -4%
substr 210818/s 4% --
100
Rate unpack substr
unpack 22015/s -- -9%
substr 24322/s 10% --
1000
Rate unpack substr
unpack 2259/s -- -9%
substr 2481/s 10% --
10000
Rate unpack substr
unpack 225/s -- -9%
substr 247/s 9% --
100000
Rate unpack substr
unpack 22.0/s -- -10%
substr 24.4/s 11% --

最佳答案

事实上,您的基准测试存在缺陷,以一种非常非常有趣的方式,但归结为您真正比较的是 unpack 与 map 可以丢弃列表的相对效率,因为 Benchmark::cmpthese() 在 void 上下文中执行函数。

您的 substr 出现在顶部的原因是 pp_ctl.c pp_mapwhile() 中的这行代码:

if (items && gimme != G_VOID) {

即,如果 perl 的 map 知道它在 void 上下文中被调用,它会神奇地跳过一堆工作(即为 map 结果分配存储空间)!

(我对 windows 与上面看到的其他人的预感是基于 windows 的 perl 内存分配很糟糕,所以跳过分配是一个更大的节省 - 只是预感,不过,我没有一个 windows 框可以玩。但实际的解包实现是直接的 C 代码,并且不应该与其他 Windows 有很大不同。)

我有三种不同的解决方案来解决这个问题并进行更公平的比较:
  • 将列表分配给数组
  • 循环遍历函数内的列表,不返回任何内容
  • 返回对列表的引用(隐藏 void 上下文)

  • 这是我的 %methods 版本,包含所有三个版本:
    my %methods = (
    unpack_assign => sub { my @foo = unpack $format_string, $data; return },
    unpack_loop => sub { for my $foo (unpack $format_string, $data) { } },
    unpack_return_ref => sub { return [ unpack $format_string, $data ] },
    unpack_return_array => sub { return unpack $format_string, $data },

    substr_assign => sub { my @foo = map {substr $data, $_, 1} 0 .. ($n_substrings - 1) },
    substr_loop => sub { for my $foo ( map {substr $data, $_, 1} 0 .. ($n_substrings - 1)) { } },
    substr_return_ref => sub { return [ map {substr $data, $_, 1} 0 .. ($n_substrings - 1) ] },
    substr_return_array => sub { return map { substr $data, $_, 1} 0 .. ($n_substrings - 1) },
    );

    我的结果:
    $ perl -v

    This is perl, v5.10.0 built for x86_64-linux-gnu-thread-multi

    $ perl foo.pl
    10
    Rate substr_assign substr_return_ref substr_loop unpack_assign unpack_return_ref unpack_loop unpack_return_array substr_return_array
    substr_assign 101915/s -- -20% -21% -28% -51% -51% -65% -69%
    substr_return_ref 127224/s 25% -- -1% -10% -39% -39% -57% -62%
    substr_loop 128484/s 26% 1% -- -9% -38% -39% -56% -61%
    unpack_assign 141499/s 39% 11% 10% -- -32% -32% -52% -57%
    unpack_return_ref 207144/s 103% 63% 61% 46% -- -1% -29% -37%
    unpack_loop 209520/s 106% 65% 63% 48% 1% -- -28% -37%
    unpack_return_array 292713/s 187% 130% 128% 107% 41% 40% -- -12%
    substr_return_array 330827/s 225% 160% 157% 134% 60% 58% 13% --
    100
    Rate substr_assign substr_loop substr_return_ref unpack_assign unpack_return_ref unpack_loop unpack_return_array substr_return_array
    substr_assign 11818/s -- -25% -25% -26% -53% -55% -63% -70%
    substr_loop 15677/s 33% -- -0% -2% -38% -40% -51% -60%
    substr_return_ref 15752/s 33% 0% -- -2% -37% -40% -51% -60%
    unpack_assign 16061/s 36% 2% 2% -- -36% -39% -50% -59%
    unpack_return_ref 25121/s 113% 60% 59% 56% -- -4% -22% -35%
    unpack_loop 26188/s 122% 67% 66% 63% 4% -- -19% -33%
    unpack_return_array 32310/s 173% 106% 105% 101% 29% 23% -- -17%
    substr_return_array 38910/s 229% 148% 147% 142% 55% 49% 20% --
    1000
    Rate substr_assign substr_return_ref substr_loop unpack_assign unpack_return_ref unpack_loop unpack_return_array substr_return_array
    substr_assign 1309/s -- -23% -25% -28% -52% -54% -62% -67%
    substr_return_ref 1709/s 31% -- -3% -6% -38% -41% -51% -57%
    substr_loop 1756/s 34% 3% -- -3% -36% -39% -49% -56%
    unpack_assign 1815/s 39% 6% 3% -- -34% -37% -48% -55%
    unpack_return_ref 2738/s 109% 60% 56% 51% -- -5% -21% -32%
    unpack_loop 2873/s 120% 68% 64% 58% 5% -- -17% -28%
    unpack_return_array 3470/s 165% 103% 98% 91% 27% 21% -- -14%
    substr_return_array 4015/s 207% 135% 129% 121% 47% 40% 16% --
    10000
    Rate substr_assign substr_return_ref substr_loop unpack_assign unpack_return_ref unpack_loop unpack_return_array substr_return_array
    substr_assign 131/s -- -23% -27% -28% -52% -55% -63% -67%
    substr_return_ref 171/s 30% -- -5% -6% -38% -42% -52% -57%
    substr_loop 179/s 37% 5% -- -1% -35% -39% -50% -55%
    unpack_assign 181/s 38% 6% 1% -- -34% -38% -49% -55%
    unpack_return_ref 274/s 109% 60% 53% 51% -- -6% -23% -32%
    unpack_loop 293/s 123% 71% 63% 62% 7% -- -18% -27%
    unpack_return_array 356/s 171% 108% 98% 96% 30% 21% -- -11%
    substr_return_array 400/s 205% 134% 123% 121% 46% 37% 13% --
    100000
    Rate substr_assign substr_return_ref substr_loop unpack_assign unpack_return_ref unpack_loop unpack_return_array substr_return_array
    substr_assign 13.0/s -- -22% -26% -29% -51% -55% -63% -67%
    substr_return_ref 16.7/s 29% -- -5% -8% -37% -43% -52% -58%
    substr_loop 17.6/s 36% 5% -- -3% -33% -40% -50% -56%
    unpack_assign 18.2/s 40% 9% 3% -- -31% -37% -48% -54%
    unpack_return_ref 26.4/s 103% 58% 50% 45% -- -9% -25% -34%
    unpack_loop 29.1/s 124% 74% 65% 60% 10% -- -17% -27%
    unpack_return_array 35.1/s 170% 110% 99% 93% 33% 20% -- -12%
    substr_return_array 39.7/s 206% 137% 125% 118% 50% 36% 13% --

    所以回到最初的问题:“unpack() 比 substr() 快吗?”回答:对于这种类型的应用程序总是如此——除非你不关心返回值;)

    关于perl - Perl 的 unpack() 比 substr() 快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1083269/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com