gpt4 book ai didi

Java:多线程字符流解码

转载 作者:太空狗 更新时间:2023-10-29 22:47:48 25 4
gpt4 key购买 nike

我正在维护一个高性能的 CSV 解析器,并尝试充分利用最新技术来提高吞吐量。对于此特定任务,这意味着:

  • 闪存(我们拥有一个相对便宜的 PCI-Express 卡,1 TB 的存储,达到 1 GB/s 的持续读取性能)
  • 多核(我们拥有一台带 16 个硬件线程的廉价 Nehalem 服务器)

CSV 解析器的第一个实现是单线程的。文件读取、字符解码、字段拆分、文本解析,都在同一个线程中。结果是大约 50MB/s 的吞吐量。不错,但远低于存储限制...

第二种实现使用一个线程读取文件(在字节级别),一个线程解码字符(从 ByteBuffer 到 CharBuffer),以及多个线程解析字段(我的意思是将分隔的文本字段解析为 double ,整数、日期...)。这工作得更快,在我们的盒子上接近 400MB/s。

但仍远低于我们存储的性能。那些 SSD 将来会再次改进,我们不会在 Java 中充分利用它。很明显,当前的限制是字符解码( CharsetDecoder.read(...) )。这就是瓶颈,在功能强大的 Nehalem 处理器上,它以 400MB/s 的速度将字节转换为字符,非常好,但这必须是单线程的。 CharsetDecoder 在某种程度上是有状态的,具体取决于使用的字符集,并且不支持多线程解码。

所以我对社区的问题是(感谢您到目前为止阅读这篇文章):有谁知道如何在 Java 中并行化字符集解码操作?

最佳答案

does anyone know how to parallelize the charset decoding operation in Java?

您也许可以打开多个输入流来执行此操作(我不确定您将如何使用 NIO 进行此操作,但这一定是可能的)。

这有多难取决于您解码的编码。您将需要针对目标编码的定制解决方案。如果编码具有固定宽度(例如 Windows-1252),则一个字节 == 一个字符并且解码很容易。

现代可变宽度编码(如 UTF-8 和 UTF-16)包含用于识别字符序列的第一个字节的规则,因此可以跳转到文件的中间并开始解码(您将拥有注意前一个 block 的结尾,因此首先开始解码文件的结尾是明智的)。

一些传统的可变宽度编码可能设计得不是很好,因此您别无选择,只能从数据的开头解码并按顺序读取。

如果可以,请将您的数据生成为 UTF-16BE。然后你可以停止解码并直接读取两个字节到一个字符。

如果文件是 Unicode,请注意 BOM 处理,但我猜您已经熟悉许多底层细节。

关于Java:多线程字符流解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3438466/

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