稀疏矩阵压缩,访问时间快

本文关键字:访问 时间 压缩 | 更新日期: 2023-09-27 18:25:06

我正在写一个lexer生成器作为一个业余项目,我想知道如何进行表压缩。所讨论的表是short的2D阵列并且非常稀疏。它们在一个维度中总是256个字符。另一个维度的大小根据lexer中的状态数而变化。

压缩的基本要求是

  • 数据应该是可访问的,而无需解压缩整个数据集。并且在常数O(1)时间内可访问
  • 计算压缩表的速度相当快

我了解行位移法,这是我目前已经实现的方法。这可能是我天真的实现,但我所拥有的生成速度慢得可怕,尽管访问速度很快。我想我可以使用一些已经建立的字符串搜索算法,比如这里的一个算法,让它更快。

我想一个选择是使用Dictionary,但这感觉像是作弊,我希望如果我使用带有一些既定算法的直数组,我能够获得快速访问时间。也许我不必要为此担心。

据我所知,flex在词法表中没有使用这种算法。相反,它似乎使用了一种名为行/列等价的东西,我真的找不到任何解释。

我真的很想知道flex使用的行/列等效算法是如何工作的,或者我是否应该为这项任务考虑其他好的选择。

编辑:详细说明此数据的实际内容。它是lexer中状态转换的状态信息。数据需要以压缩格式存储在内存中,因为状态表可能很大。也正是从这个内存中,可以直接访问实际值,而无需解压缩表。我有一个使用行位移的工作解决方案,但它的计算速度非常慢——部分原因是我的实现很愚蠢。

也许我对行位移方法的实现会让我们更清楚地了解如何访问这些数据。它有点冗长,我希望我把它放在pastebin上而不是这里没关系。

数据非常稀疏。它通常是一大串零,然后是每个州的几个空头。例如,对其进行游程编码是微不足道的,但它会破坏线性访问时间。

Flex显然有两对表,basedefault用于第一对,nextcheck用于第二对。这些表似乎以我不理解的方式相互索引。龙之书试图解释这一点,但就像那本神秘知识的大部头经常发生的情况一样,它所说的在像我这样的小人物身上消失了。

稀疏矩阵压缩,访问时间快

本文,http://www.syst.cs.kumamoto-u.ac.jp/~masato/cgi-bin/rp/files/p606-tarjan.pdf描述了一种压缩稀疏表的方法,可能对此感兴趣。

你的表事先知道吗?你只需要一种有效的方式来存储和访问它们吗?

我真的不熟悉问题域,但如果你的表沿着一个轴有一个固定的大小(256),那么一个大小为256的数组,其中每个元素都是可变长度的向量,会起作用吗?你想在给定(x,y)对的情况下挑出一个元素吗?

我一直想用的另一个很酷的解决方案是一个完美的哈希表,http://burtleburtle.net/bob/hash/perfect.html,您可以从数据中生成哈希函数,这样您将获得最小的空间需求和O(1)查找(即没有冲突)。

这些解决方案都没有采用任何类型的压缩,尽管它们只是将浪费的空间量降至最低。。

不清楚的是,您的表在一个维度或另一个维度中是否具有"序列属性"。

序列特性在人类语音中自然发生,因为一个单词由许多字母组成,字母的序列很可能在以后出现。它在二进制程序、源代码等中也很常见。

另一方面,采样数据,如原始音频、地震值等,并没有公布序列特性。他们的数据仍然可以压缩,但使用另一个模型(例如简单的"德尔塔模型",然后是"熵")。

如果你的数据在2个维度中的任何一个维度上都具有"序列属性",那么你可以使用通用的压缩算法,这将给你带来速度和可靠性。你只需要为它提供一个"顺序友好"的输入(即选择你的维度)。

如果你关心速度,你可以看看这个C#实现的快速压缩器,它也是一个非常快速的解压缩器:https://github.com/stangelandcl/LZ4Sharp