iOS Tutorial Fast arrays access

Discussion in 'iOS Tutorials' started by Erel, May 13, 2018.

  1. Erel

    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:
    Code:
    Dim data(10000000As 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 * 4As 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:
    Code:
    Dim data(1000000 * 4As Byte
    - Getting an element from the array is done with Bit.FastArrayGetByte / Int / Float:
    Code:
    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:
    Code:
    Bit.FastArraySetFloat(data, 21000'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.
     
  2. sorex

    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?
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    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:
    Code:
    Dim data(10000000As 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
     
    Johan Hormaza and OliverA like this.
Loading...