0.3.0 BoolArray

This commit is contained in:
Rob Tillaart 2024-04-11 15:34:44 +02:00
parent 50372e006c
commit 212c71fc4b
17 changed files with 435 additions and 46 deletions

View File

@ -1,4 +1,4 @@
# These are supported funding model platforms
github: RobTillaart
custom: "https://www.paypal.me/robtillaart"

View File

@ -1,13 +1,13 @@
name: Arduino-lint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: arduino/arduino-lint-action@v1
with:
library-manager: update
compliance: strict
compliance: strict

View File

@ -1,4 +1,3 @@
---
name: Arduino CI
on: [push, pull_request]
@ -6,9 +5,10 @@ on: [push, pull_request]
jobs:
runTest:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6

View File

@ -9,10 +9,10 @@ on:
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: json-syntax-check
uses: limitusus/json-syntax-check@v1
uses: limitusus/json-syntax-check@v2
with:
pattern: "\\.json$"
pattern: "\\.json$"

View File

@ -1,7 +1,7 @@
//
// FILE: BoolArray.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.8
// VERSION: 0.3.0
// DATE: 2015-12-06
// PURPOSE: BoolArray library for Arduino
// URL: https://github.com/RobTillaart/BoolArray
@ -11,6 +11,10 @@
#include "BoolArray.h"
/////////////////////////////////////////////////////////
//
// 16 bit version
//
BoolArray::BoolArray()
{
_array = NULL;
@ -26,7 +30,11 @@ BoolArray::~BoolArray()
uint8_t BoolArray::begin(const uint16_t size)
{
if (size > BOOLARRAY_MAXSIZE) return BOOLARRAY_SIZE_ERROR;
// is this test needed....
if (size > BOOLARRAY_MAXSIZE)
{
return BOOLARRAY_SIZE_ERROR;
}
// do we need to re-allocate?
if (_size != size)
{
@ -37,6 +45,12 @@ uint8_t BoolArray::begin(const uint16_t size)
free(_array);
}
_array = (uint8_t *) malloc(_bytes);
if (_array == NULL)
{
_size = 0;
_bytes = 0;
return BOOLARRAY_INIT_ERROR;
}
}
return BOOLARRAY_OK;
}
@ -48,7 +62,7 @@ uint16_t BoolArray::size()
}
uint8_t BoolArray::memory()
uint16_t BoolArray::memory()
{
return _bytes;
}
@ -110,5 +124,140 @@ uint8_t BoolArray::toggle(const uint16_t index)
}
/////////////////////////////////////////////////////////
//
// 32 bit version for large bool arrays
//
BoolArray32::BoolArray32()
{
_array = NULL;
_size = 0;
}
BoolArray32::~BoolArray32()
{
if (_array) free(_array);
}
uint8_t BoolArray32::begin(const uint32_t size)
{
if (size > BOOLARRAY_MAXSIZE)
{
return BOOLARRAY_SIZE_ERROR;
}
// do we need to re-allocate?
if (_size != size)
{
_size = size;
_bytes = (_size + 7) / 8;
if (_array)
{
free(_array);
}
_array = (uint8_t *) malloc(_bytes);
if (_array == NULL)
{
_size = 0;
_bytes = 0;
return BOOLARRAY_INIT_ERROR;
}
}
return BOOLARRAY_OK;
}
uint32_t BoolArray32::size()
{
return _size;
}
uint32_t BoolArray32::memory()
{
return _bytes;
}
uint8_t BoolArray32::setAll(const uint8_t value)
{
if (_array == NULL)
{
return BOOLARRAY_INIT_ERROR;
}
uint8_t *p = _array;
uint32_t t = _bytes;
if (value == 0)
{
while (t--) *p++ = 0;
}
else
{
while (t--) *p++ = 0xFF;
}
return BOOLARRAY_OK;
}
uint8_t BoolArray32::clear()
{
return setAll(0);
}
uint8_t BoolArray32::get(const uint32_t index)
{
if (_array == NULL)
{
return BOOLARRAY_INIT_ERROR;
}
if (index >= _size)
{
return BOOLARRAY_SIZE_ERROR;
}
uint32_t by = index / 8;
uint8_t bi = index & 7;
return (_array[by] & _masks[bi]) > 0;
}
uint8_t BoolArray32::set(const uint32_t index, const uint8_t value)
{
if (_array == NULL)
{
return BOOLARRAY_INIT_ERROR;
}
if (index >= _size)
{
return BOOLARRAY_SIZE_ERROR;
}
uint32_t by = index / 8;
uint8_t bi = index & 7;
if (value == 0) _array[by] &= ~_masks[bi];
else _array[by] |= _masks[bi];
return BOOLARRAY_OK;
}
uint8_t BoolArray32::toggle(const uint32_t index)
{
if (_array == NULL)
{
return BOOLARRAY_INIT_ERROR;
}
if (index >= _size)
{
return BOOLARRAY_SIZE_ERROR;
}
uint32_t by = index / 8;
uint8_t bi = index & 7;
_array[by] ^= _masks[bi];
return BOOLARRAY_OK;
}
// -- END OF FILE --

View File

@ -2,7 +2,7 @@
//
// FILE: BoolArray.h
// AUTHOR: Rob Tillaart
// VERSION: 0.2.8
// VERSION: 0.3.0
// DATE: 2015-12-06
// PURPOSE: BoolArray library for Arduino
// URL: https://github.com/RobTillaart/BoolArray.git
@ -15,9 +15,11 @@
#include "Arduino.h"
#define BOOLARRAY_LIB_VERSION (F("0.2.8"))
#define BOOLARRAY_LIB_VERSION (F("0.3.0"))
#define BOOLARRAY_MAXSIZE (250 * 8) // 2000
#ifndef BOOLARRAY_MAXSIZE
#define BOOLARRAY_MAXSIZE (1250 * 8) // 8000
#endif
#define BOOLARRAY_OK 0x00
#define BOOLARRAY_ERROR 0xFF
@ -25,6 +27,10 @@
#define BOOLARRAY_INIT_ERROR 0xFD
/////////////////////////////////////////////////////////
//
// 16 bit version
//
class BoolArray
{
public:
@ -34,7 +40,7 @@ public:
uint8_t begin(const uint16_t size);
uint16_t size();
uint8_t memory();
uint16_t memory();
uint8_t setAll(const uint8_t value);
uint8_t clear();
@ -46,7 +52,37 @@ private:
uint8_t _masks[8] = {1, 2, 4, 8, 16, 32, 64, 128};
uint8_t * _array;
uint16_t _size = 0;
uint8_t _bytes = 0;
uint16_t _bytes = 0;
};
/////////////////////////////////////////////////////////
//
// 32 bit version for large bool arrays
// separate class as it is slower
//
class BoolArray32
{
public:
BoolArray32();
~BoolArray32();
uint8_t begin(const uint32_t size);
uint32_t size();
uint32_t memory();
uint8_t setAll(const uint8_t value);
uint8_t clear();
uint8_t get(const uint32_t index);
uint8_t set(const uint32_t index, const uint8_t value);
uint8_t toggle(const uint32_t index);
private:
uint8_t _masks[8] = {1, 2, 4, 8, 16, 32, 64, 128};
uint8_t * _array;
uint32_t _size = 0;
uint32_t _bytes = 0;
};

View File

@ -6,11 +6,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.3.0] - 2024-04-10
- made BOOLARRAY_MAXSIZE a -D command line define option
- increased default BOOLARRAY_MAXSIZE to 1250 x 8 = 10000 booleans
- about Arduino UNO max size
- add BoolArray32 class for larger arrays.
- update GitHub actions
----
## [0.2.8] - 2023-02-08
- update readme.md
- optimize begin - test for need to reallocate.
## [0.2.7] - 2023-02-08
- update readme.md
- update GitHub actions

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2015-2023 Rob Tillaart
Copyright (c) 2015-2024 Rob Tillaart
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -26,11 +26,29 @@ You need to check if your application needs more performance than this library c
#### Notes
The BoolArray class allocates dynamic memory.
The **BOOLARRAY_MAXSIZE** is set to 2000, this was chosen as **malloc()** can only allocate 255 bytes
in one call on an UNO. This is not checked with the recent versions of the IDE any more.
The **BOOLARRAY_MAXSIZE** is set to 10000 (booleans).
This number is chosen as it is about the maximum one can allocate in one call on an UNO.
If one want to allocate more booleans, adjust the **BOOLARRAY_MAXSIZE**.
This can be done as a command line option.
The library is tested on AVR architecture only.
#### BoolArray32
Since 0.3.0 a **BoolArray32** class is added - **experimental** for now.
Where the **BoolArray** class can have max 65535 booleans, the **BoolArray32** class
has a 32 bit interface allowing up to 4 billion++ booleans in theory.
Although most IOT devices would not have enough memory, it allows one to have more than
65535 booleans.
Also it might be that the **BoolArray32** class is faster on some platforms
that are native 32 bit (not verified yet).
On an Arduino UNO the **BoolArray32** class is slower.(verified).
#### Related
The BitArray library is one from a set of three:
@ -44,6 +62,30 @@ BoolArray is faster than BitArray as it only supports single bits and does not n
of different bytes to read/write a value. However BoolArray currently only supports 2000 bits while
BitArray can support more.
## Performance
See **boolArrayDemo0.ino**
Indicative performance figures.
| class | function | UNO | ESP32 | Notes |
|:--------------|:-----------:|:-------:|:--------:|:--------:|
| BoolArray | set(0) | 10.37 | |
| BoolArray | set(1) | 10.25 | |
| BoolArray | get(i) | 16.03 | |
| BoolArray | setAll(0) | 96 | | per 2000
| BoolArray | setAll(1) | 100 | | per 2000
| | | | |
| BoolArray32 | set(0) | 15.97 | |
| BoolArray32 | set(1) | 15.84 | |
| BoolArray32 | get(i) | 24.20 | |
| BoolArray32 | setAll(0) | 148 | | per 2000
| BoolArray32 | setAll(1) | 144 | | per 2000
- UNO 16 MHz, ESP32 240 MHz.
- toggle() is expected to be similar to set()
- clear() is a wrapper around setAll(0) so similar.
## Interface
@ -55,22 +97,24 @@ BitArray can support more.
- **BoolArray()** Constructor
- **~BoolArray()** Destructor
- **uint8_t begin(uint16_t size)** dynamically allocates size elements (8 bools in one byte).
- **uint8_t begin(uint32_t size)** dynamically allocates size elements (8 booleans in one byte).
Returns **BOOLARRAY_OK** on success.
#### Meta
- **uint16_t size()** returns number of bool elements.
- **uint16_t size()** returns number of boolean elements.
- **uint16_t memory()** returns number of bytes used.
#### Base
The following functions return **BOOLARRAY_OK** on success.
- **uint8_t setAll(uint8_t value)** Sets all elements to false (0) or true (all other values).
- **uint8_t clear()** Sets all elements to false.
- **uint8_t get(uint16_t index)** Return 0 or 1 OR an error value which can be interpreted as true.
So one need to check these carefully.
- **uint8_t set(uint16_t index, uint8_t value)** Set the element to false (0) or true (all other values).
- **uint8_t toggle(uint16_t index)** Toggles element at index. Returns **BOOLARRAY_OK** on success.
- **uint8_t toggle(uint16_t index)** Toggles element at index.
## Future
@ -84,18 +128,19 @@ So one need to check these carefully.
- performance test on ESP32
- performance for **clear()** dedicated loop vs **setAll(0)** call
- performance intern 16 bit iso 8 bit. (0.3.0)
- faster on UNO
- does allocation work as it should?
- investigate template class
- improve allocation (see PrintCharArray)
#### Could
- update examples.
- boolArray32() class
- begin(uint32_t size);
- investigate **uint32_t array[N]** for BoolArray32 (ESP32?)
- adjust math
#### Wont
- performance intern 16 bit instead of 8 bit is NOT faster on UNO
## Support

View File

@ -2,7 +2,6 @@
// FILE: boolArrayDemo0.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo performance reading boolean array
// DATE: 2015-12-06
// URL: https://github.com/RobTillaart/BoolArray
@ -21,14 +20,17 @@ uint32_t duration1, duration2;
void setup()
{
Serial.begin(115200);
Serial.print("Start ");
Serial.println(__FILE__);
Serial.print("LIB VERSION:\t");
Serial.print("BOOLARRAY_LIB_VERSION:\t");
Serial.println(BOOLARRAY_LIB_VERSION);
int rv = b.begin(BOOLARRAY_MAXSIZE);
Serial.print("SIZE:\t");
int rv = b.begin(2000);
Serial.print("SIZE bits:\t");
Serial.println(b.size());
Serial.print("MEM bytes:\t");
Serial.println(b.memory());
Serial.print("freeMemory:\t");
Serial.println(freeMemory());
if (rv != BOOLARRAY_OK)
{
@ -191,5 +193,33 @@ void test3()
}
// -- END OF FILE --
#ifdef AVR
extern unsigned int __bss_end;
extern unsigned int __heap_start;
extern void *__brkval;
int freeMemory()
{
int free_memory;
if ((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
return free_memory;
};
#else
int freeMemory()
{
return 0;
};
#endif
// -- END OF FILE --

View File

@ -0,0 +1,63 @@
BOOLARRAY_LIB_VERSION: 0.3.0
SIZE bits: 2000
MEM bytes: 250
freeMemory: 1250
TEST SET(1)
DURATION: 26412
DURATION: 47156
20744 10.37
TEST SET(0)
DURATION: 26156
DURATION: 46660
20504 10.25
TEST GET(i)
DURATION: 37728
DURATION: 69792
32064 16.03
TEST SET(0): 26156
TEST SETALL(0): 96
FACTOR: 272.46
TEST SET(1): 26412
TEST SETALL(1): 100
FACTOR: 264.12
Done...
/////////////////////////////////////////
//
// BoolArray32 == slower
//
BOOLARRAY_LIB_VERSION: 0.3.0
SIZE bits: 2000
MEM bytes: 250
freeMemory: 1246
TEST SET(1)
DURATION: 40116
DURATION: 72060
31944 15.97
TEST SET(0)
DURATION: 39864
DURATION: 71548
31684 15.84
TEST GET(i)
DURATION: 56596
DURATION: 105000
48404 24.20
TEST SET(0): 39864
TEST SETALL(0): 148
FACTOR: 269.35
TEST SET(1): 40116
TEST SETALL(1): 144
FACTOR: 278.58
Done...

View File

@ -2,7 +2,6 @@
// FILE: boolArrayDemo2.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo performance boolean array
// DATE: 2015-12-12
// URL: https://github.com/RobTillaart/BoolArray
@ -19,7 +18,6 @@ volatile long x = 0;
void setup()
{
Serial.begin(115200);
Serial.print("Start ");
Serial.println(__FILE__);
Serial.print("BOOLARRAY_LIB_VERSION:\t");
Serial.println(BOOLARRAY_LIB_VERSION);

View File

@ -0,0 +1,59 @@
///////////////////////////////////////////////
//
// BOOLARRAY
//
BOOLARRAY_LIB_VERSION: 0.2.7
Bool array size: 1000
get
DURATION: 5160
DURATION: 9876
X: 0
set
DURATION: 3968
DURATION: 7488
clear
DURATION: 48164
DURATION: 96076
setAll
DURATION: 48164
DURATION: 96076
toggle
DURATION: 3840
DURATION: 7232
Done...
///////////////////////////////////////////////
//
// BOOLARRAY32
//
BOOLARRAY_LIB_VERSION: 0.3.0
Bool array size: 1000
get
DURATION: 7420
DURATION: 14028
X: 0
set
DURATION: 5728
DURATION: 10624
clear
DURATION: 65204
DURATION: 130148
setAll
DURATION: 73124
DURATION: 145996
toggle
DURATION: 5600
DURATION: 10376
Done...

View File

@ -2,14 +2,15 @@
# Data types (KEYWORD1)
BoolArray KEYWORD1
BoolArray32 KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
size KEYWORD2
memory KEYWORD2
setAll KEYWORD2
setAll KEYWORD2
clear KEYWORD2
get KEYWORD2
set KEYWORD2

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/BoolArray.git"
},
"version": "0.2.8",
"version": "0.3.0",
"license": "MIT",
"frameworks": "*",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=BoolArray
version=0.2.8
version=0.3.0
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for compact array of booleans of max size 2000 (UNO).

View File

@ -39,11 +39,11 @@ unittest_teardown()
unittest(test_constants)
{
assertEqual(2000, BOOLARRAY_MAXSIZE );
assertEqual(0x00, BOOLARRAY_OK );
assertEqual(0xFF, BOOLARRAY_ERROR );
assertEqual(0xFE, BOOLARRAY_SIZE_ERROR);
assertEqual(0xFD, BOOLARRAY_INIT_ERROR);
assertEqual(10000, BOOLARRAY_MAXSIZE );
assertEqual(0x00, BOOLARRAY_OK );
assertEqual(0xFF, BOOLARRAY_ERROR );
assertEqual(0xFE, BOOLARRAY_SIZE_ERROR);
assertEqual(0xFD, BOOLARRAY_INIT_ERROR);
}