我有一个整数数组
a = [1,2,3,4]
当我这样做时
a.join
Ruby内部调用to_s
方法4次,这对我的需求来说太慢了。
将大量整数输出到控制台的最快方法是什么?
我的意思是:
a = [1,2,3,4........,1,2,3,9], should be:
1234 ........ 1239
答案 0 :(得分:3)
如果要将整数打印到stdout,则需要先将其转换为字符串,因为这是所有stdout都能理解的。如果要将两个整数打印到stdout,则需要先将它们都转换为字符串。如果要将三个整数打印到stdout,则需要先将它们中的所有三个转换为字符串。如果要将十亿个整数打印到stdout,则需要先将所有十亿个整数转换为字符串。
你,我们或者Ruby,或者任何编程语言都无法做到这一点。
您可以通过执行延迟流实现来尝试将转换与I / O交错。您可以通过执行延迟流实现并将转换和I / O分成两个单独的线程来尝试并行执行转换和I / O. (确保使用实际上执行并行线程的Ruby实现,但并非所有这些线程都可以:例如,MRI,YARV和Rubinius都不能。)
您可以并行化转换,方法是在单独的线程中转换数组中的单独块。您甚至可以同时购买十亿个核心机器并同时转换十亿个整数。
但即便如此,事情仍然存在:每个整数都需要转换。你是先做一个接一个,然后打印出来,或者一个接一个地与I / O交错,或者一个接一个地与I / O并行完成,或者甚至将它们全部转换成同一个十亿核心CPU的时间:所需转换的数量并没有神奇地减少。大量整数意味着大量转换。即使您在十亿个核心CPU中并行执行了十亿次转换,它仍然十亿次转换,即十亿次调用to_s
。
答案 1 :(得分:2)
如上面的评论所述,如果Fixnum.to_s
的表现不够快,那么你真的需要考虑Ruby是否是这项特定任务的正确工具。
但是,您可以做的一些事情可能适用于您的情况,也可能不适用。
如果数组的构建发生在时间关键区域之外,那么构建数组,或者使用字符串而不是整数来创建数组的副本。通过我10000次整数的小测试,这大约快了5倍。
如果您同时控制读取和写入过程,则使用Array.pack
写入输出,并使用String.unpack
来读取结果。这可能不会更快,因为即使元素已经是整数,包似乎也会调用Fixnum.to_int
。
我希望这些数据与每个版本的Ruby都不同,因此值得检查您的特定目标版本。
答案 2 :(得分:0)
程序的缓慢不是来自to_s
被调用4次,而是从打印到控制台。控制台输出很慢,你无法对它做任何事情。
答案 3 :(得分:0)
对于个位数,您可以执行此操作
[1,2,3,4,5].map{|x|(x+48).chr}.join
如果您需要加快更大的数字,可以尝试记住to_s
答案 4 :(得分:0)
除非你真的需要在控制台上看到数字(听起来像你没有),然后将它们写入二进制文件 - 应该快得多。
如果您需要这样做,您可以将二进制文件传输到其他程序中,而不仅仅是文本。