I'm writing a Dart library in which I'm very regularly dealing with byte arrays or byte strings. Since Dart doesn't have a byte type nor an array type, I'm using List for all byte arrays.
Is this a good practice to do? I only recently found out about the existence of Uint8List
in the dart:typed_data
package. It's clear that this class aims to by the go-to implementation for byte arrays.
But does it have any direct advantages?
I can imagine that it does always perform checks on new items so that the user can make sure no non-byte-value integers are inside the list. But are there other advantages or differences?
There also is a class named ByteArray, but it seems to be a quite inefficient alternative for List...
The advantage should be that the Uint8List consumes less memory than a normal List, because it is known from the beginning that each elements size is a single byte. Uint8List can also be mapped directly to underlying optimized Uint8List types (e.g. in Javascript). Copies of list slices are also easier to perform, because all bytes are laid-out continguos in memory and therefore the slice can be directly copied in a single operation to another Uint8List (or equivalent) type.
However if this advantage is fully used depends on how good the implementation of Uint8List in Dart is.
John Mccutchan of the Dart team explains that the Dart VM relies on 3 different integer representations — pretty like the Three Musketeer's, there is the small machine integer (smi), the medium (mint) and the big heavy integer (bint). The VM takes care to switch automatically between the three depending on the size of the integer in play.
Within the smi range, which depends on the CPU architecture, integers fit in a register, therefore can be loaded and stored directly in the field instead of being fetched from memory. They also never require memory allocation. Which leads to the performance side of the story: within the smi range, storing an integer in object lists is faster than putting them in a typed list.
Typed lists would have to tag and untags, steps which refer to the VM set of operations to box and unbox smi values without allocation memory or loading the value from a object. The leaner, the better.
On the other hand, typed list have two big capabilities to consider. The garbage collection is very low as typed lists can store never store object references, only numbers. Typed list can also be much more dense therefore an Int8List would require much less memory and make better use of CPU's cache. The smi range principle applies also in typed lists, so playing with numbers within that range provides the best performance.
All in all, what remains of this is that we need to benchmark each approach to find which work the best depending on the situation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With