11

我正在编写一个 Dart 库,我经常在其中处理字节数组或字节字符串。由于 Dart 既没有字节类型也没有数组类型,所以我将 List 用于所有字节数组。

这是一个好习惯吗?我最近才发现包中Uint8List存在dart:typed_data。很明显,这个类旨在通过字节数组的首选实现。

但它有任何直接的优势吗?

我可以想象它总是对新项目执行检查,以便用户可以确保列表中没有非字节值整数。但是还有其他优点或区别吗?

还有一个名为 ByteArray 的类,但它似乎是 List 的一个非常低效的替代方案......

4

3 回答 3

9

优点应该是 Uint8List 比普通 List 消耗更少的内存,因为从一开始就知道每个元素的大小都是一个字节。Uint8List 也可以直接映射到底层优化的 Uint8List 类型(例如在 Javascript 中)。列表切片的副本也更容易执行,因为所有字节在内存中都是连续布局的,因此可以在单个操作中直接将切片复制到另一个 Uint8List(或等效)类型。

但是,能否充分利用这一优势取决于 Dart 中 Uint8List 的实现有多好。

于 2013-11-11T11:58:51.480 回答
3

Dart 团队的 John Mccutchan解释说,Dart VM 依赖于 3 种不同的整数表示 - 很像三剑客的,有小机器整数 (smi)、中 (mint) 和大重整数 (bint)。VM 会根据整数的大小在三者之间自动切换。

在取决于 CPU 架构的 smi 范围内,整数适合寄存器,因此可以直接加载和存储在字段中,而不是从内存中获取。它们也从不需要内存分配。这导致了故事的性能方面:在 smi 范围内,将整数存储在对象列表中比将它们放入类型列表中更快

类型化的列表必须标记和取消标记,这些步骤指的是 VM 操作集以对 smi 值进行装箱和拆箱,而无需分配内存或从对象加载值。越瘦越好。

另一方面,类型化列表有两大功能需要考虑。垃圾收集非常低,因为类型列表可以存储从不存储对象引用,只存储数字。类型化列表也可以更密集,因此 Int8List 将需要更少的内存并更好地利用 CPU 的缓存。smi 范围原则也适用于类型列表,因此使用该范围内的数字可提供最佳性能。

总而言之,剩下的就是我们需要对每种方法进行基准测试,以根据情况找到最有效的方法。

于 2014-02-27T13:30:10.507 回答
0

Uint8List是一个 8 位整数的无符号列表,比List<int>处理大量二进制数据时更有效。

字节数据由 a 支持BytesBuffer,您可以获得底层字节的不同视图。例如,您可以将 8 位、16 位、32 位或 64 位块中的字节视为有符号或无符号整数。

对于大于 8 位的块,您需要注意字节顺序,这受底层机器或存储格式的影响。您可以使用ByteData指定大端或小端视图。

Uint8ListList<int>大型列表更有效。Uint8List 是一个整数列表,其中列表中的值每个只有 8 位或一个字节。Uint8List 的 U 表示无符号,因此值范围从 0 到 255。这非常适合表示二进制数据!

于 2022-02-12T03:31:55.933 回答