iOS Tutorial Fast arrays access

Erel

Administrator
Staff member
Licensed User
B4i v5.0 adds several methods to the Bit object that provide very fast access to arrays.

In most cases there is no reason to use these methods as they are more cumbersome and less safe than the standard way to access arrays.
If your performance critical code does many reads or writes to arrays then you should consider switching to the "fast methods". 'Many' means millions+ reads or writes.

With these methods as well as other internal optimizations, BitmapCreator runs 10x - 30x faster in v5.0 than in previous versions: https://www.b4x.com/android/forum/threads/b4i-v5-00-beta-has-been-released.92855/#content

Lets start with an example:
B4X:
Dim data(10000000) As Int 'length = 10 million
Dim n As Long = DateTime.Now
For i = 0 To data.Length - 1
   data(i) = data(i) + 1
Next
Label1.Text = $"Regular array: ${DateTime.Now - n}ms"$

Dim data2(data.Length * 4) As Byte
Dim n As Long = DateTime.Now
For i = 0 To data2.Length / 4 - 1
   Bit.FastArraySetInt(data2, i, Bit.FastArrayGetInt(data2, i) + 1)
Next
Label2.Text = $"Fast array: ${DateTime.Now - n}ms"$
The results are:
646ms for the standard method.
38ms for the fast methods.

How to use?

- Create an array of bytes. The data will be stored in this array.
- The elements types can be Int, Float or Byte.
The length of Ints and Floats is 4 bytes. So if you want to create an array that will store 1,000,000 floats then you need to declare it like this:
B4X:
Dim data(1000000 * 4) As Byte
- Getting an element from the array is done with Bit.FastArrayGetByte / Int / Float:
B4X:
Dim f As Float = Bit.FastArrayGetFloat(data, 2) 'returns the 3rd element.
Dim last As Float = Bit.FastArrayGetFloat(data, 999999) 'returns the last element
- Setting the elements values is done with Bit.FastArraySetByte / Int / Float:
B4X:
Bit.FastArraySetFloat(data, 2, 1000) 'sets the 3rd element value to 1000.
If you use data.Length then you must remember to divide it by 4 (for ints and floats) as demonstrated in the first example.
Bounds are not checked. Hard to debug errors happen if you try to access elements outside of the array.
 

sorex

Expert
Licensed User
nice, it reminds me of the assembly stosd method which allows storing data with 4 bytes as once.

is this something IOS specific or is this coming to B4A/B4J aswell?
 

Erel

Administrator
Staff member
Licensed User
is this something IOS specific or is this coming to B4A/B4J aswell?
It is specific to B4i. The arrays access is done with C pointers. It is not something that can be done in Java. On the other hand the standard array methods in B4A and B4J are faster so it is less needed any way.

A very non-accurate comparison of this same unrealistic loop in B4J and B4A:
B4X:
Dim data(10000000) As Int 'length = 10 million
Dim n As Long = DateTime.Now
For i = 0 To data.Length - 1
   data(i) = data(i) + 1
Next
Label1.Text = $"Regular array: ${DateTime.Now - n}ms"$
B4J: 10ms (The PC is more powerful than a mobile device).
B4A: 130ms
 
Top