是否可以预定义 Str 的初始大小?

Bra*_* P. 7 raku

在某些语言中,开发人员可以指定字符串的初始大小。Raku有类似的东西吗?我有一个字符串,我将在其中连接文本几千次。可以在创建字符串之前计算最终大小。我想测试一下是否可以节省几百毫秒的时间。

Eli*_*sen 7

简短回答:不。

更长的答案:当您在 MoarVM 后端的 Rakudo 中连接字符串时,您实际上并没有创建连接的字符串:在内部,您有一个由单独的字符串片段组成的对象。

只有一种情况是字符串实际上被连接起来的:那就是当你在正则表达式中将它用作大海捞针时。我相信字符串的“片段”有最大数量,当达到最大数量时,将导致内存中的实际连接。

如果您正在考虑优化:那么不要每次都连接,而是推送到本机str数组,完成后,那么.join

my str @parts;
while $todo {
    @parts.push: "foo";
}
@parts.join
Run Code Online (Sandbox Code Playgroud)

这通常更快,因为 您正在使用本机字符串,并且b。所有的串联逻辑(实际上并不像您想象的那么简单,因为例如变音符号代码点可以位于部分的开头,并且可能需要与前一部分的最后一个代码点连接)可以在VM 无需在 VM 的 HLL 操作和 C 代码之间切换。

  • 一些基准:`my str @a; @a.push(~$_) 为 ^1000000;@a.join` 的速度大约是 `my Str @a; 的 3 倍;@a.push(~$_) 为 ^1000000;@a.join` (3认同)

jub*_*us1 5

为了补充 @ElizabethMattijsen 的出色答案:

这取决于“初始大小”的含义。如果您通过 获取字符串IO,而不是使用类似的东西,lines您可以尝试 Raku 函数readchars,该函数采用$chars默认为 的分隔符65536

https://docs.raku.org/routine/readchars

限制readchars字符串字符长度 ( $chars) 可能会给您带来所需的加速:

~$ raku -e 'my $fh = open $*IN; given $fh { say .readchars: 5; .close;}'  letters_one_per_line.txt
a
b
c
Run Code Online (Sandbox Code Playgroud)

当您说“连接”文本时,这些文本是来自文件的连续片段吗?如果是这样,那么readchars你的朋友就是:

~$ raku -e 'my $fh = open $*IN; given $fh { $_.readchars( 5 ).print xx 2; .close;}' letters_one_per_line.txt
a
b
c
d
e
Run Code Online (Sandbox Code Playgroud)

此外,Perl 有一个众所周知的IO::String模块,它由同名的 RakuIO::String模块复制到 Raku 生态系统中。据称,这些模块使您正在解决的问题更容易处理:

https://raku.land/github:hoelzro/IO::String

不幸的是,RakuIO::String模块已经很多年没有更新了。但也许OP的兴趣会刺激进一步的发展!

HTH。