【发布时间】:2012-01-18 19:28:21
【问题描述】:
谁能解释使用Data.Text和Data.ByteString.Char8数据类型的利弊?使用纯 ASCII 文本会改变这些优点和缺点吗?他们的懒惰变种也改变了故事吗?
【问题讨论】:
标签: haskell text bytestring
谁能解释使用Data.Text和Data.ByteString.Char8数据类型的利弊?使用纯 ASCII 文本会改变这些优点和缺点吗?他们的懒惰变种也改变了故事吗?
【问题讨论】:
标签: haskell text bytestring
Data.ByteString.Char8 提供将ByteString 值视为8 位ASCII 字符序列的函数,而Data.Text 是支持整个Unicode 的独立类型。
ByteString 和 Text 本质上是相同的,就表示而言——严格的、未装箱的数组,具有基于严格块列表的惰性变体。主要区别在于ByteString 存储八位字节(即Word8s),而Text 存储Chars,以UTF-16 编码。
如果您使用纯 ASCII 文本,那么使用 Data.ByteString.Char8 可能会比 Text 更快,并且使用更少的内存;但是,您应该问自己是否真的确定您只会使用 ASCII。基本上,在 99% 的情况下,使用 Data.ByteString.Char8 而不是 Text 是一种加速技巧——八位字节 不是 字符,任何 Haskeller 都同意使用 正确 type 应该优先于原始的裸机速度。如果您已经分析了程序并且它是一个瓶颈,您通常应该只考虑它。 Text 进行了很好的优化,在大多数情况下差异可能可以忽略不计。
当然,在某些与速度无关的情况下,Data.ByteString.Char8 是有保证的。考虑一个包含本质上是二进制数据的文件,而不是文本,而是分成几行;使用lines 是完全合理的。此外,完全可以想象,在二进制格式的上下文中,整数可能会以 ASCII 十进制编码。在这种情况下,使用 readInt 会很有意义。
所以,基本上:
Data.ByteString.Char8:适用于性能至关重要的纯 ASCII 情况,以及处理包含一些 ASCII 组件的“几乎二进制”数据。Data.Text:文本,包括任何可能使用非 ASCII 码的情况。【讨论】:
Data.ByteString.Char8,因为您实际上将处理仅类似于文本的二进制格式。 (我还建议查看 attoparsec 以解析文件。)
Text 会将每个字符编码为两个字节,但ByteString 会将它们编码为一个。不过,如果您目前使用的是String,我不会太担心; String 有 huge 开销(每个字符 5 个字(!)),远远超过其他两个。见this summary of memory footprints。
String 受益于共享,而ByteString 和Text,作为未装箱的数组,不要;然而,ByteString 和 Text 都采用子字符串而不复制,而且它们一开始就小得多,你必须非常努力地使这个缺点变得重要。