Raku :有没有一种超级快速的方法可以将数组转换为字符串而不用空格分隔元素?
Raku : is there a SUPER fast way to turn an array into a string without the spaces separating the elements?
我需要将数以千计的二进制字节字符串(每个大约一兆字节长)转换为 ASC 字符串。这是我一直在做的,但似乎太慢了:
sub fileToCorrectUTF8Str ($fileName) { # binary file
my $finalString = "";
my $fileBuf = slurp($fileName, :bin);
for @$fileBuf { $finalString = $finalString ~ $_.chr; };
return $finalString;
}
~@b 把@b 变成字符串,所有元素用space 分隔,但这不是我想要的。如果@b = < a b c d >; ~@b 是 "a b c d";但我只想要 "abcd",而且我想非常快地完成此操作。
那么,最好的方法是什么?我不能真正使用 hyper 进行并行处理,因为最终的字符串是按顺序构造的。或者我可以吗?
TL;DR 在旧的 rakudo 上,.decode
大约快 100 倍。
以更长的形式匹配您的代码:
sub fileToCorrectUTF8Str ($fileName) { # binary file
slurp($fileName, :bin).decode
}
性能说明
首先,这是我为测试而写的:
# Create million and 1 bytes long file:
spurt 'foo', "1234\n6789\n" x 1e5 ~ 'Z', :bin;
# (`say` the last character to check work is done)
say .decode.substr(1e6) with slurp 'foo', :bin;
# fileToCorrectUTF8Str 'foo' );
say now - INIT now;
在 TIO.run 的 2018.12
rakudo 上,上述 .decode
每百万字节文件的重量约为 .05
秒,而不是大约 5
秒为您的解决方案。
你 could/should 当然在你的系统上测试 and/or 使用更高版本的 rakudo。我希望差异保持相同的顺序,但绝对时间会随着岁月的流逝而显着改善。[1]
为什么速度快了 100 倍?
嗯,首先,@
在 Buf
/ Blob
上明确强制 raku 查看以前的 单个项目 (a 缓冲区)作为 plural 事物(元素的 list 又名 multiple items)。这意味着高级迭代,对于一百万个元素缓冲区,立即是 百万 高级 iterations/operations 而不是 一个 高级操作。
其次,使用 .decode
不仅避免了迭代,而且只会招致相对较慢的 方法调用 每个文件一次的开销,而在迭代时可能有一百万次 .chr
每个文件调用。方法调用(至少在语义上)是 late-bound,这 原则上 与调用 sub 而不是一种方法(潜艇通常是早期绑定)。
综上所述:
记住警告为空[1]。例如,rakudo 的标准 类 生成方法缓存,编译器可能只是内联方法,所以方法调用方面的开销可以忽略不计。
另请参阅文档的 Performance page, especially Use existing high performance code。
Buf.Str
错误信息是LTA吗?
更新见Liz++的评论
如果您尝试在 Buf
或 Blob
上使用 .Str
(或等效的,例如在其上使用 ~
前缀),您将得到一个例外。当前消息是:
Cannot use a Buf as a string, but you called the Str method on it
doc for .Str
on a Buf
/Blob
目前说:
In order to convert to a Str you need to use .decode
.
可以说是 LTA,错误消息没有提示相同的事情。
再一次,在决定对此采取什么措施之前,如果有的话,我们需要考虑人们 可以 从任何错误中吸取教训,包括有关的信号它,例如错误消息,以及它们 做 实际上目前学习的内容和方式,并使我们的反应偏向于建立 正确的 文化和基础设施.
特别是,如果人们可以轻松地将他们看到的错误消息与详细说明该消息的在线讨论联系起来,则需要考虑并鼓励 and/or 变得更容易。
例如,现在有这个 SO 涵盖了这个问题,其中包含错误消息,因此 google 很可能会在这里找到某人。依靠它可能是比更改错误消息更合适的前进道路。或者它可能不会。改变会很容易...
请考虑在下方评论 and/or 搜索现有的 rakudo issues to see if improvement of the Buf.Str
error message is being considered and/or whether you wish to open an issue to propose it be altered. Every rock moved is at least great exercise, and, as our collective effort becomes increasingly wise, improves (our view of) the mountain。
脚注
[1] 正如众所周知的拉丁谚语 Caveat Empty 所说,任何特定 raku 功能的绝对和相对性能,以及更一般地说,任何特定代码总是会因各种因素而发生变化,这些因素包括一个人的系统功能、运行 编译代码期间的负载,以及编译器所做的任何优化。因此,例如,如果您的系统是 "empty",那么您的代码可能 运行 更快。或者,作为另一个示例,如果您等待一年或三年让编译器变得更快,advances in rakudo's performance continue to look promising.
我需要将数以千计的二进制字节字符串(每个大约一兆字节长)转换为 ASC 字符串。这是我一直在做的,但似乎太慢了:
sub fileToCorrectUTF8Str ($fileName) { # binary file
my $finalString = "";
my $fileBuf = slurp($fileName, :bin);
for @$fileBuf { $finalString = $finalString ~ $_.chr; };
return $finalString;
}
~@b 把@b 变成字符串,所有元素用space 分隔,但这不是我想要的。如果@b = < a b c d >; ~@b 是 "a b c d";但我只想要 "abcd",而且我想非常快地完成此操作。
那么,最好的方法是什么?我不能真正使用 hyper 进行并行处理,因为最终的字符串是按顺序构造的。或者我可以吗?
TL;DR 在旧的 rakudo 上,.decode
大约快 100 倍。
以更长的形式匹配您的代码:
sub fileToCorrectUTF8Str ($fileName) { # binary file
slurp($fileName, :bin).decode
}
性能说明
首先,这是我为测试而写的:
# Create million and 1 bytes long file:
spurt 'foo', "1234\n6789\n" x 1e5 ~ 'Z', :bin;
# (`say` the last character to check work is done)
say .decode.substr(1e6) with slurp 'foo', :bin;
# fileToCorrectUTF8Str 'foo' );
say now - INIT now;
在 TIO.run 的 2018.12
rakudo 上,上述 .decode
每百万字节文件的重量约为 .05
秒,而不是大约 5
秒为您的解决方案。
你 could/should 当然在你的系统上测试 and/or 使用更高版本的 rakudo。我希望差异保持相同的顺序,但绝对时间会随着岁月的流逝而显着改善。[1]
为什么速度快了 100 倍?
嗯,首先,@
在 Buf
/ Blob
上明确强制 raku 查看以前的 单个项目 (a 缓冲区)作为 plural 事物(元素的 list 又名 multiple items)。这意味着高级迭代,对于一百万个元素缓冲区,立即是 百万 高级 iterations/operations 而不是 一个 高级操作。
其次,使用 .decode
不仅避免了迭代,而且只会招致相对较慢的 方法调用 每个文件一次的开销,而在迭代时可能有一百万次 .chr
每个文件调用。方法调用(至少在语义上)是 late-bound,这 原则上 与调用 sub 而不是一种方法(潜艇通常是早期绑定)。
综上所述:
记住警告为空[1]。例如,rakudo 的标准 类 生成方法缓存,编译器可能只是内联方法,所以方法调用方面的开销可以忽略不计。
另请参阅文档的 Performance page, especially Use existing high performance code。
Buf.Str
错误信息是LTA吗?
更新见Liz++的评论
如果您尝试在 Buf
或 Blob
上使用 .Str
(或等效的,例如在其上使用 ~
前缀),您将得到一个例外。当前消息是:
Cannot use a Buf as a string, but you called the Str method on it
doc for .Str
on a Buf
/Blob
目前说:
In order to convert to a Str you need to use
.decode
.
可以说是 LTA,错误消息没有提示相同的事情。
再一次,在决定对此采取什么措施之前,如果有的话,我们需要考虑人们 可以 从任何错误中吸取教训,包括有关的信号它,例如错误消息,以及它们 做 实际上目前学习的内容和方式,并使我们的反应偏向于建立 正确的 文化和基础设施.
特别是,如果人们可以轻松地将他们看到的错误消息与详细说明该消息的在线讨论联系起来,则需要考虑并鼓励 and/or 变得更容易。
例如,现在有这个 SO 涵盖了这个问题,其中包含错误消息,因此 google 很可能会在这里找到某人。依靠它可能是比更改错误消息更合适的前进道路。或者它可能不会。改变会很容易...
请考虑在下方评论 and/or 搜索现有的 rakudo issues to see if improvement of the Buf.Str
error message is being considered and/or whether you wish to open an issue to propose it be altered. Every rock moved is at least great exercise, and, as our collective effort becomes increasingly wise, improves (our view of) the mountain。
脚注
[1] 正如众所周知的拉丁谚语 Caveat Empty 所说,任何特定 raku 功能的绝对和相对性能,以及更一般地说,任何特定代码总是会因各种因素而发生变化,这些因素包括一个人的系统功能、运行 编译代码期间的负载,以及编译器所做的任何优化。因此,例如,如果您的系统是 "empty",那么您的代码可能 运行 更快。或者,作为另一个示例,如果您等待一年或三年让编译器变得更快,advances in rakudo's performance continue to look promising.