【问题标题】:Efficient way to combine a lazy ByteString and a lazy Text组合惰性 ByteString 和惰性 Text 的有效方法
【发布时间】:2022-11-16 03:34:03
【问题描述】:

我正在编写一些呈现 HTML 页面的代码(通过 servant,如果相关的话),由于各种复杂的原因,我必须通过“组合”两个部分来构造 HTML。

  • 从返回Data.ByteString.Lazy 的内部 HTTP API 获取一个段
  • 另一个片段使用ede 库呈现,它生成一个Data.Text.Lazy

如果我必须有效地组合这两个部分,我有什么选择?这两个片段可以相当大(每个片段只有 100 kb)。这个servant 服务器会看到相当多的流量,所以任何低效率(比如为每个请求/请求复制 100 秒的内存,都会很快累加起来)。

【问题讨论】:

  • 在段的生成过程中发生的任何不平凡的事情肯定会超过将其中一个片段复制为另一个片段的格式所带来的开销。 (如果只是发生一些微不足道的事情,那么调整代码以立即提供首选类型应该很容易。)但是,如果这些段是独立的,为什么不生成两个 HTML 文件并在客户端将它们组合起来呢?
  • 另外...您确定首先需要这么多动态生成的 HTML 代码吗?将常量部分外包给 CDN 和/或以有效的二进制格式存储任何数据部分将比您在存储 HTML 的 Haskell 类型方面所做的任何事情都更能提高性能。
  • @leftaroundabout 无法在客户端真正组合这些段。惰性的 ByteString 段实际上是页面的布局(页眉+页脚)。惰性文本部分是页面的正文/主要内容。他们必须在提供给客户端之前在服务器端进行组合。
  • @leftaroundabout 从 CPU 的角度来看,我同意与访问数据库相比,数据复制可能不会成为瓶颈。但是在高负载/流量下的内存使用情况呢?
  • @leftaroundabout 预生成 HTML 并存储在 Redis 或 CDN 中将是我的下一步,但我很好奇如何完成这项工作。

标签: haskell bytestring


【解决方案1】:

假设你的端点返回一个惰性的ByteString,使用Data.Text.Lazy.Encoding的函数encodeUtf8将你的惰性Text转换为惰性的ByteString,然后返回两个惰性的ByteStringappend

在内部,lazy ByteStrings 基本上是严格的ByteString 块的列表。连接它们是列表连接,并且不会为字节本身产生新的分配。

惰性字节向量的时间和空间高效实现,使用 打包的 Word8 数组列表

某些操作,例如 concat、append、reverse 和 cons,具有更好的 比它们的 Data.ByteString 等价物复杂,由于 列表脊柱结构产生的优化。

如果你有大量的 lazy ByteStrings 而不是两个,你应该采取额外的步骤使用 lazyByteString 将它们转换为 Builders,连接 Builders,然后得到结果 lazy @987654342 @使用toLazyByteString。这样可以避免left-associated list concatenation的低效率。

构建器表示字节序列。它们是 mempty 所在的幺半群 零长度序列和 mappend 是串联的,运行在 O(1)。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-21
  • 2011-11-06
相关资源
最近更新 更多