加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何在Ruby中有效地切片二进制数据?

发布时间:2020-12-17 03:42:46 所属栏目:百科 来源:网络整理
导读:在检查了SO Ruby: Split binary data后,我使用了以下代码. z = 'A' * 1_000_000z.bytes.each_slice( STREAMING_CHUNK_SIZE ).each do | chunk | c = chunk.pack( 'C*' )end 但是,它很慢: Benchmark.realtime do ...= 0.0983949700021185 98ms切片并打包1MB
在检查了SO Ruby: Split binary data后,我使用了以下代码.

z = 'A' * 1_000_000
z.bytes.each_slice( STREAMING_CHUNK_SIZE ).each do | chunk | 
  c = chunk.pack( 'C*' )
end

但是,它很慢:

Benchmark.realtime do
  ...
=> 0.0983949700021185

98ms切片并打包1MB文件.这很慢.

使用案例:
服务器从外部API接收二进制数据,并使用socket.write chunk.pack(‘C *’)对其进行流式处理.
数据预计在50KB到5MB之间,平均为500KB.

那么,如何在Ruby中有效地分割二进制数据呢?

解决方法

笔记

您的代码看起来不错,使用正确的Ruby方法和正确的语法,但它仍然:

>创建一个巨大的整数数组
>在多个阵列中切割这个大数组
>将这些数组打包回String

替代

以下代码直接从字符串中提取部分,而不转换任何内容:

def get_binary_chunks(string,size)
  Array.new(((string.length + size - 1) / size)) { |i| string.byteslice(i * size,size) }
end

(string.length size – 1)/ size)只是为了避免丢失最后一个chunk,如果它小于size.

性能

使用500kB的pdf文件和12345字节的块,Fruity返回:

Running each test 16 times. Test will take about 28 seconds.
_eric_duminil is faster than _b_seven by 380x ± 100.0

在这个例子中,get_binary_chunks也比StringIO#each(n)快6倍.

进一步优化

如果你确定该字符串是二进制的(不是带有多字节字符的UTF8,如’?’),则可以使用slice而不是byteslice

def get_binary_chunks(string,size)
  Array.new(((string.length + size - 1) / size)) { |i| string.slice(i * size,size) }
end

这使得代码更快(与您的方法相比大约500倍).

如果将此代码与Unicode字符串一起使用,则块将具有大小字符,但可能具有大于字节的大小.

直接使用块

最后,如果您对获取字符串数组不感兴趣,可以直接使用这些块:

def send_binary_chunks(socket,string,size)
  ((string.length + size - 1) / size).times do |i|
    socket.write string.slice(i * size,size)
  end
end

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读