对于“大”编解码器,Scala阶段类型器在直接从HList创建编解码器并应用.dropUnits时需要花费很长时间(我们正在谈论的时间)
( ignore(6) ::
uint(2) ::
uint(30) ::
int(4) ::
int(8) ::
uint(10) ::
bool(1) ::
int(28) ::
int(27) ::
uint(12) ::
uint(9) ::
uint(6) ::
int(2) ::
ignore(3) ::
bool(1) ::
uint(19)
).dropUnits.as[SomeBigCaseClass]用~创建一个编解码器,然后像这样应用.hlist似乎要快得多:
( ignore(6) ~
uint(2) ~
...
).hlist.dropUnits.as[SomeBigCaseClass]但这看起来不管用。
Could not prove that this.Out can be converted to/from reports.SomeBigCaseClass.
).hlist.dropUnits.as[SomeBigCaseClass]
^我找到的最简单的解决方案(对我来说足够好)是忽略Unit值。
( (ignore(6) dropLeft
uint(2)) ::
...
).as[SomeBigCaseClass]对于许多忽略的编解码器来说,这个特性将是非常受欢迎的。我做错了什么?我是不是完全没听懂.hlist的意思?
发布于 2015-01-26 14:23:31
hlist组合器将Codec[A]转换为Codec[A :: HNil]。这通常用于其他组合器,如flatZip,这需要一个基于HList的编解码器。
重复使用~运算符将创建一个基于左关联的Tuple2结构。例如,int8 ~ bool ~ int8有Codec[((Int, Boolean), Int)]类型。最新的scodec快照1.7.0-快照(虽然不是1.7.0-RC1)具有flattenLeftPairs方法,该方法将左关联的元组编解码器转换为等效的HList编解码器。
scodec的未来版本将有一个像~这样的组合器,但是它将创建TupleN实例,而不是嵌套Tuple2实例。例如:int8 ~~ bool ~~ int8将具有Codec[(Int, Boolean, Int)]类型。不过,这一问题尚未得到整合。通过减少分配的元组数量,这既具有性能优势,也具有方便性优势,因为它允许通过widenOpt(SomeBigCaseClass.apply, SomeBigCaseClass.unapply)绑定到case类。
最后,使用dropUnits观察到的编译器性能问题确实是组合器定义方式的一个问题。这已经修正在scodec core 1.7.0-快照中(但不是1.7.0-RC1 )。见https://github.com/scodec/scodec/issues/41。
https://stackoverflow.com/questions/28109303
复制相似问题