gpt4 book ai didi

java - 单个大文件的并行压缩

转载 作者:行者123 更新时间:2023-12-04 07:50:48 50 4
gpt4 key购买 nike

有没有办法在 Java 中进行并行压缩?
我目前正在使用 ParallelScatterZipCreator但不幸的是,它对每个文件进行并行压缩。因此,如果存在比其他文件大得多的单个文件,则并行压缩仅适用于较小的文件。然后它必须等到大文件被串行压缩。
即使我们正在压缩单个文件,是否有更好的库可以利用所有 CPU 内核?

最佳答案

TL;DR:您可能根本不需要压缩。如果你这样做,那么你可能不想使用 zip 格式,它是过时的技术,有很大的缺点,显然你有一些相当具体的需求。您可能想要 ZStandard (zstd)。
压缩是如何工作的
压缩的工作原理是查看一团字节并在其中找到某种形式的重复。因此,不可能压缩单个字节。
这使得工作 从根本上与并行化不一致 :如果您将一个 100 万字节的 blob 压缩成 10 个块,每个块 100k 字节,单独压缩每个 miniblob,那么任何重复使得其中一个在一个 miniblob 中,另一个在另一个中,意味着您已经错过了压缩数据的机会,如果您将这些数据压缩到一个 blob 中,您就不会错过。
唯一的原因 ZIP 让你并行化一点,是因为它是一种旧格式 - 在当时是明智的,但在这个时代,几乎 ZIP 格式的每个部分都是废话。
为什么 ZIP 不好?
ZIP 是一个混合包,将两个不相关的工作混为一谈。

  • 一个捆绑器。捆绑工具是一些软件,它接收一堆文件并将其转换为单个流(单个字节)。为此,捆绑工具将获取有关文件的元数据(其名称、其所有者/组或其他访问信息、其上次修改时间等)及其中的数据,并将其序列化为单个流。 zip 这样做,例如posix tar工具。
  • 一个压缩机。压缩器获取数据流并通过查找重复模式对其进行压缩。

  • zip 本质上只是 #1,但作为捆绑器的一部分,带有“此文件中的数据”的部分有一个标志,表明压缩算法已应用于表示数据的字节。理论上,您几乎可以使用任何算法,但实际上, zip 文件有 全部 使用 DEFLATE 算法压缩的条目,该算法远不如更现代的算法。 .tar.gz是完全相同的技术(首先捆绑它:tar 文件,然后 gzip tar 文件。gzip 是 DEFLATE 算法),但在某些情况下效率更高(它对整个流应用压缩,而不是从头开始为每个文件重新启动。如果您携带 1000 个类似的小文件,那么 .tar.gz 格式的文件比 .zip 格式的文件小几个数量级)。
    此外,zip 很旧,它当时做出的选择是有道理的,但在现代系统中很愚蠢:您不能“流式传输”zip(在收到整个文件之前,您无法有意义地开始解压缩一个),因为捆绑程序的信息在 结束的文件。
    那么为什么我可以并行化 zip 呢?
    因为 zip 会在每个文件上“重新启动”它们的压缩窗口。这是低效的,并且会损害 zip 文件的压缩率。
    如果需要,您可以将完全相同的原则应用于任何数据块。用压缩效率换取可并行性。 ZIP 是一种没有用的格式;正如你所说,如果你有一个更大的文件,这一点没有实际意义。
    'restart window at' 是一个可以推广的原则,各种压缩格式以更有用的方式支持它(每 X 字节重新启动,而 ZIP 不可靠的'在每个文件重新启动')。
    瓶颈是什么?
    发送数据时涉及多个方面:源提供您想要发送的字节的速度,将字节处理成可以发送的包的速度(例如,zip 工具,但可以是任何东西,包括只是逐字发送,未压缩),打包字节传输到目标系统的速度,目标可以解包的速度,以及目标可以处理解包结果的速度。
    您确定压缩方面是瓶颈吗?
    在基本情况下,您从硬盘读取字节,将它们压缩,通过住宅互联网管道将它们发送到另一个系统,该系统解压缩并将它们保存在 HDD 上,瓶颈很可能是网络.并行压缩步骤完全是浪费,实际上 只会减慢速度 通过降低压缩比。
    如果您从旋转盘上读取文件,那么源的速度可能是瓶颈,并行处理 大大减慢了速度 :您现在要求读取磁头来回弹跳,这比一次性顺序读取数据要慢得多。
    如果你有一个快速的源和一个快速的管道,那么瓶颈无疑是压缩和解压缩,但解决方案是 完全不压缩 :如果您要从 SSD 或从 USB3 连接的字节喷射传感器传输数据,并通过 10M CAT6 电缆从一个千兆以太网端口传输到另一个,那么为什么要压缩?只需发送这些字节。压缩不会让它变得更快,只要您不使 1Gb 连接饱和,尝试压缩它就绝对不会获得任何好处。
    如果你的管道很慢,那么让事情变得更快的唯一方法就是尽可能多地压缩。这绝对不涉及使用 DEFLATE 算法(例如,不要使用 zip)。使用另一种算法并配置它以获得更好的压缩率,但代价是 CPU 性能。并行化无关紧要;这不是瓶颈,所以这样做没有任何意义。
    结论
    很可能您想通过未压缩的方式发送文件,或者通过 ZStandard 发送文件,根据需要调整压缩率与速度比。我不知道 java 本身有任何 ZStandard (zstd) impl,但是 zstd-jni项目为您提供了一个基于 Java 的 API,用于调用 C zstd 库。
    如果您坚持使用 ZIP,那么答案是一个相当基本的“不,您不能真正这样做”,尽管理论上您可以编写一个并行 ZIP 压缩器,它具有更差的压缩能力但并行化更好(通过在单个窗口内重新启动窗口)文件用于更大的文件,除了在每个文件上强制您按格式重新启动),并生成仍然与地球上几乎所有解压缩工具兼容的 ZIP 文件。我不知道有一个,我不认为存在一个,并且自己编写一个绝对是一项非常重要的练习。

    关于java - 单个大文件的并行压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66989293/

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