- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想用Java创建一个快速的霍夫曼代码解码器,因此考虑了查找表。由于这些表占用内存,并且我们使用Java代码导航和访问表,因此可以轻松(或不容易)编写表示同一表的程序/方法。
这种方法的问题是,我不知道什么是最佳策略。我知道很多有关缓存和分支预测的内容。同样,切换案例的实现意味着实际的ASM不在我范围内。如果我有一个内存中查找表(或它的层次结构),则可以简单地跳入和跳出,但是出于我的目的,我建议将该表放入高速缓存中。
由于我实际上走了一棵树,因此可以像执行其他语句一样需要一定数量的比较来实现它,但是对于每个比较,则需要附加的二进制运算。
因此存在以下选项:
内存查找表中使用的通用算法
决策树的if / else表示
if / else表示法,使用小的switch语句查找正确的符号组(相同的位模式长度)(如果if语句较少,则可能是更多代码)。
代码的switch语句表示
编写和进行基准测试非常棘手,因此任何初步想法都会很棒。
起作用的另一个问题是位的顺序。最重要的位始终位于最前面,这意味着它以相反的顺序存储。
如果您的树是A = 0,B = 10,C = 11以编写BAC,则它实际上是01 + 0 + 11(加上意味着追加)。
因此,实际上必须以相反的顺序编写代码。对组使用if / else或switch方法将不会有问题,因为屏蔽位很简单,并且位的反转也很可能,但是由于相反,它将失去使组内的索引脱离掩码的想法位顺序的添加和删除具有不同的含义,并且不可能进行简单的查找。
反转位是一项昂贵的操作(我使用4位查找表),不会超过二进制操作的性能损失。
但是,在旅途中反转位更适合此操作,并且每位需要进行四个操作(上移,屏蔽,加法以及下移输入)。由于我提前读取了所有这些位,因此所有这些操作都将在寄存器中完成,因此它们可能只需要几个周期。
这样,我可以使用switch,sub和if来找到正确的符号组并返回它们。
最后,我需要一些建议。由于我的代码在语言处理方面是全球通用的,因此可以进行硬连线(即在源代码中)。
我不知道像ANTRL这样的解析器生成器用来表达那些决定。由于他们也根据输入符号来缝制切换或是否/其他,这可能会给我一个提示。
[更新]
我发现了一种简化方法,可以避免反向位问题,但仍会增加每组的成本。因此,我最终按照要遍历的组的顺序编写了位。因此,我不需要每个位四个修改,而是每个组(不同的位长)。
对于每个组,我们有:
1.第一个元素的值,大小(以及该组中最后一个元素的值)。
因此,对于每个组,算法如下:
1.读取兆位并与当前读取值合并。
2.将值与该组的最后一个值进行比较,如果该值不在该组中,则该值在该组中较小。 ->继续阅读
3.如果它在组中,则可以访问值数组或使用switch语句。
这是完全通用的,可以不使用循环就可以有效地使用。同样,如果检测到该组,则代码的位长是已知的,并且可以从源中消耗这些位,因为代码看起来很远(从流中读取)。
[更新2]
要访问实际值,可以使用按组分组的单个大元素数组。由于按组分组的可传输性降低,因此很可能有相当一部分适合L2或L1缓存,从而加快了访问速度。
或者使用switch语句。
[更新3]
根据开关的情况,编译器会生成表开关或查找开关。查找开关的复杂度为O(log n),并且存储密钥,jmp偏移对,因此不理想。因此,检查组更适合if / else。
tableswitch本身仅使用跳转偏移量表,并且仅需进行减法,比较,访问,jmp即可到达目标,而它必须对常量执行返回值。
因此,表访问看起来更有希望。另外,为避免不必要的跳转,每个组可能包含访问和返回组符号表的逻辑。将所有内容存储在一个大表中是有希望的,因为每个符号可能是int或short,而我的代码通常最多只有1000到4000个符号,这实际上使它很短。
我将检查1-模式是否将使我有机会以更好的方式存储和访问掩码,从而允许二进制搜索正确的组而不是前进O(n),甚至可能在处理期间完全避免任何移位操作。
最佳答案
我无法理解您在(长)问题中写的大部分内容,但是有一个简单的方法。
我们将从一个表开始。假设您最长的霍夫曼代码是15位。 (实际上,deflate将其霍夫曼代码的大小限制为15位。)然后构造一个包含32768个条目的表,其中每个条目是下一个代码中的位数,以及该代码的符号。对于少于15位的代码,同一代码在表中有多个条目。例如。如果符号“ C”的代码是10010110(7位),则表xxxxxxxx10010110的所有索引都相同。这些条目都带有{7,'C'}。
然后,您从流中获得15位,并查找表中的下一个代码。您从该表条目中删除位数,并使用结果符号。现在,您需要从流中获取尽可能多的位,并具有15位,然后重复。因此,如果您使用了7位,则再增加8位回到15,然后查找下一个代码。
下一个微妙之处是,如果您的霍夫曼代码经常更改,那么您可能最终要花更多的时间为每个新的霍夫曼代码填充大表,而不是实际解码。为了避免这种情况,您可以创建一个两级表,该表具有一个用于代码第一部分的9位查找(512个条目)。如果代码为9位或更少,则按上述步骤进行。这将是最常见的情况,因为较短的代码会更频繁(这是霍夫曼编码的重点)。如果表条目表明代码中有10位或更多位(并且您还不知道还有多少位),那么您将消耗前9位,并转到第二级表以查找所指向的前9位按第一个表中的条目,它具有其余六个位的条目(64个条目)。这样可以解决代码的其余部分,从而告诉您要消耗多少位以及什么是符号。这种方法可以极大地减少花费在填充表上的时间,并且由于短代码更为常见,因此速度几乎一样快。这是inflate中zlib使用的方法。
关于java - Java源代码生成中的霍夫曼代码解码器编码器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28851223/
我有课 class Header { @FCBTag(type="type1") --My custom annotation int a = "valueA"; @FCBTa
我一直在使用 Apache MINA 并正在学习 Netty。我过去使用过 MINA 累积编码器/解码器,我有兴趣看看 Netty 是否有类似的功能。我查看了 API,但没有看到任何内容。 最佳答案
我有一组使用 wsdl2java (Axis 1.4) 创建的类,我正在寻找一种方法来解码和编码来自/到字符串和对象的数据。我已经编写了一个 JAXB 解码器,它适用于我们的一些较新的内部对象,因为我
在我的自定义类 WLNetworkClient 中,我必须实现这样的方法: required init(coder aDecoder: NSCoder) { fatalError("init(
基于 transformer 的编码器-解码器模型是 表征学习 和 模型架构 这两个领域多年研究成果的结晶。本文简要介绍了神经编码器-解码器模型的历史,更多背景知识,建议读者阅读由 Seba
在使用 FFMPEG android java 库时发生以下异常的视频播放速度(使视频变慢)。 [aac @ 0x416c26f0] The encoder 'aac' is experimental
我正在从一个程序运行 ffmpeg,我们自己构建了 ffmpeg(我们没有使用包管理器或预构建的东西安装它)。 这是构建的命令: 2020-07-31 12:14:11.942 INFO ffmpeg
许多基于LSTM的seq2seq编码器-解码器架构教程(例如英法翻译),将模型定义如下: encoder_inputs = Input(shape=(None,)) en_x= Embedding(
如何覆盖使用 marshmallow 的 JSON 编码器库,以便它可以序列化 Decimal字段?我想我可以通过覆盖 json_module 来做到这一点在基地Schema或 Meta课,但我不知道
在我的 Grails 2.5.0 应用程序中,我使用了一组自定义 JSON 编码器来严格控制由我的 REST 端点返回的 JSON 格式。目前我在这样的服务中注册这些编码器 class Marshal
我需要多个自定义 JSON 编码器,因为我想针对不同的目的以不同的方式进行编码。我知道如何使用以下方法设置自定义编码器应用程序: JSON.registerObjectMarshaller(MyCla
查看文档,它是这样说的: https://netty.io/4.0/api/io/netty/channel/ChannelPipeline.html A user is supposed to ha
我希望为以下案例类提供 JSON 编码器: import io.circe.generic.extras.Configuration final case class Hello[T]( so
我正在构建一个 JPEG 图像编码器。就目前情况而言,为了对图像进行编码,用户输入他们希望编码的文件的名称以及由此创建的文件的名称。 我希望用户能够在命令行中设置编码的质量。我尝试重命名 new Jp
我有想要在 webview 中显示的 html 文本。 如specification ,数据必须经过 URI 转义。所以我尝试使用 URLEncoder.encode() 函数,但这对我没有帮助,因为
我目前正在自己实现 PNG 滤镜。我正在使用神经网络尝试创建比当前现有的 PNG 过滤器更好的预测: 0 - 无 1 - 子 2 - 向上 3 - 平均 4 - 派斯 5 - 我的实现(使用神经网
让我们假设我们有与 Schema 一致的 XML 和带有一些公共(public)字段的 Java 类: public clas
在我的 Java 应用程序中,我正在寻找 URLEncoder.encode(String s, String enc) 的流媒体版本.我想使用“application/x-www-form-urle
我确实有一个对象层次结构,我想使用“import javax.xml.bind.Marshaller”将其从 Java 对象转换为 xml。我的java类文件被编码在“Cp1252”中,我无法更改它。
使用 Netty 4.0.27 和 Java 1.8.0_20 所以我试图通过构建一个简单的聊天服务器(我猜是典型的网络教程程序?)来了解 Netty 的工作原理。设计我自己的简单协议(protoco
我是一名优秀的程序员,十分优秀!