Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the advantages of using Uint8List over List<int> when dealing with byte arrays in Dart?

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...

like image 909
Steven Roose Avatar asked Nov 11 '13 02:11

Steven Roose


2 Answers

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.

like image 82
Matthias247 Avatar answered Sep 20 '22 07:09

Matthias247


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.

like image 28
nunobaba Avatar answered Sep 17 '22 07:09

nunobaba