Data.Text与Data.ByteString.Char8的区别

22
有没有人能解释一下使用 Data.TextData.ByteString.Char8 数据类型的利弊?仅使用ASCII文本是否会改变这些利弊?它们的lazy变体是否也会改变情况?
1个回答

30

Data.ByteString.Char8提供了将ByteString值视为8位ASCII字符序列的函数,而Data.Text是一种独立的类型,支持Unicode的全部内容。

ByteStringText在表示方面本质上是相同的——严格、非装箱数组,基于严格块列表的惰性变体。主要区别在于ByteString存储八位字节(即Word8),而Text则存储使用UTF-16编码的Char

如果你正在处理仅包含ASCII文本,则使用Data.ByteString.Char8可能比Text更快,并且占用的内存更少;然而,你应该问自己是否确实确定只会使用ASCII。在99%的情况下,使用Data.ByteString.Char8代替Text是一种速度优化——八位字节不是字符,任何Haskeller都可以同意,优先使用正确的类型而不是原始的裸速度。通常只有在程序经过剖析并成为瓶颈时才应考虑使用它。 Text经过了良好的优化,在大多数情况下差异可能是微不足道的。

当然,有一些与速度无关的情况适用于 Data.ByteString.Char8。考虑一个包含数据的文件,该数据实际上是二进制数据而不是文本,但是被分隔成行;使用 lines 是完全合理的。此外,在二进制格式的上下文中,整数可能以 ASCII 十进制编码;在这种情况下使用 readInt 是很合理的。
所以,基本上:
  1. Data.ByteString.Char8:针对纯 ASCII 的情况,性能至关重要,并处理具有某些 ASCII 组件的“几乎二进制”数据。
  2. Data.Text:文本,包括任何可能使用除 ASCII 以外字符的情况。

我可以保证只有ASCII文本,因为我的程序处理非常特定的计算机生成的C文件。无论如何,我都会尝试两种方法。 - Thomas Eding
我可能会选择 Data.ByteString.Char8,因为你实际上将处理一种类似文本的二进制格式。(我还建议查看 attoparsec 以解析文件。) - ehird
您还提到文本编码为UTF-16,而字节字符串则是八位组。这是否会对内存使用产生一般性的影响?我的应用程序是一个代码重写器,目前它使用了大量的内存,我可以追踪到这是由于使用String造成的。我已经对字符串进行了intern处理,因此任何改进都将受到欢迎。这就是为什么我想要更改数据类型的原因。 - Thomas Eding
2
@trinithis:如果你的数据全部都是ASCII,那么“Text”将会将每个字符编码为两个字节,但是“ByteString”将他们编码为一个。不过,如果你目前正在使用“String”,我不会太过担心;“String”有着巨大的开销(每个字符需要5个单词!),要比其他两种方式多得多。请参阅这篇关于内存占用的总结 - ehird
3
当然,你应该记住String受益于共享,而ByteStringText作为非装箱数组则没有;然而,ByteStringText都可以在不复制的情况下接受子字符串,它们本来就比String小得多,所以你需要很努力才能使这个缺点变得重要。 - ehird

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接