From d9affe61089ed074447e8fdc9c9f8d95aeb1c971 Mon Sep 17 00:00:00 2001 From: rob tillaart Date: Sat, 7 Mar 2015 18:46:16 +0100 Subject: [PATCH] + version 0.1.07 + substantial faster first/next/last/prev; interface + small changes in allTest.ino + added output files for version 0.1.06 and 0.1.07 (AVR 16MHZ) --- libraries/Set/Set.cpp | 93 +++++++++++-------- libraries/Set/Set.h | 9 +- libraries/Set/examples/allTest/allTest.ino | 10 ++ .../Set/examples/allTest/reference 0.1.06.txt | 87 +++++++++++++++++ .../Set/examples/allTest/reference 0.1.07.txt | 87 +++++++++++++++++ 5 files changed, 245 insertions(+), 41 deletions(-) create mode 100644 libraries/Set/examples/allTest/reference 0.1.06.txt create mode 100644 libraries/Set/examples/allTest/reference 0.1.07.txt diff --git a/libraries/Set/Set.cpp b/libraries/Set/Set.cpp index 0d5e7933..4813e2cb 100644 --- a/libraries/Set/Set.cpp +++ b/libraries/Set/Set.cpp @@ -1,11 +1,12 @@ // // FILE: Set.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.1.06 +// VERSION: 0.1.07 // PURPOSE: SET library for Arduino // URL: // // HISTORY: +// 0.1.07 faster first/next/last/prev; interface // 0.1.06 added flag to constructor to optimize +,-,*, // set -> Set // 0.1.05 bug fixing + performance a.o. count() @@ -32,7 +33,7 @@ Set::Set(bool clear) } } -Set::Set(Set &t) +Set::Set(const Set &t) { for (uint8_t i=0; i<32; i++) { @@ -72,7 +73,6 @@ bool Set::has(uint8_t v) return (_mem[idx] & mask) > 0; } -// TODO OPTIMIZE COUNT uint8_t Set::count() { uint8_t cnt = 0; @@ -80,10 +80,13 @@ uint8_t Set::count() { // kerningham bit count trick uint8_t b = _mem[i]; + if (b!=0) + { for (; b; cnt++) { b &= b-1; } + } } return cnt; } @@ -106,31 +109,37 @@ void Set::invert() int Set::first() { - for (int i = 0; i < 256; i++) - { - if (has(i)) - { - _current = i; - return _current; - } - } - _current = -1; - return _current; + return findNext(0,0); } int Set::next() { - if (_current != -1) + if (_current & 0x8000) return -1; + _current++; + uint8_t p = (uint8_t)_current / 8; + uint8_t q = (uint8_t)_current & 7; + return findNext(p, q); +} + +int Set::findNext(uint8_t p, uint8_t q) +{ + for (uint8_t i=p; i<32; i++) { - _current++; - for (int i = _current; i < 256; i++) + uint8_t b = _mem[i]; + if (b != 0) { - if (has(i)) + uint8_t mask = 1< -1; --i) - { - if (has(i)) - { - _current = i; - return _current; - } - } - } - _current = -1; - return _current; + if (_current & 0x8000) return -1; + _current--; + uint8_t p = (uint8_t)_current / 8; + uint8_t q = (uint8_t)_current & 7; + return findPrev(p, q); } int Set::last() { - _current = -1; - for (int i = 255; i >=0; --i) + return findPrev(31, 7); +} + +int Set::findPrev(uint8_t p, uint8_t q) +{ + uint8_t m = 1 << q; + for (uint8_t i=p; i!=255; --i) { - if (has(i)) + uint8_t b = _mem[i]; + if (b != 0) { - _current = i; - break; + uint8_t mask = m; + for (uint8_t j=q; j!=255; --j) + { + if (b & mask) + { + _current = i*8 + j; + return _current; + } + mask >>= 1; + } } + m = 1<<7; + q = 7; } + _current = -1; return _current; } diff --git a/libraries/Set/Set.h b/libraries/Set/Set.h index b0db32ec..f6d608d6 100644 --- a/libraries/Set/Set.h +++ b/libraries/Set/Set.h @@ -1,7 +1,7 @@ // // FILE: Set.h // AUTHOR: Rob Tillaart -// VERSION: 0.1.06 +// VERSION: 0.1.07 // PURPOSE: SET library for Arduino // URL: // @@ -18,13 +18,13 @@ #include #endif -#define SET_LIB_VERSION "0.1.06" +#define SET_LIB_VERSION "0.1.07" class Set { public: Set(bool clear = true); // create empty Set - Set(Set &t); // create copy Set + Set(const Set &t); // create copy Set void clr(); // clear the Set void invert(); // flip all elements in the Set @@ -54,9 +54,12 @@ public: int prev(); // find previous element int last(); // find last element + private: uint8_t _mem[32]; // can hold 0..255 int _current; + int findNext(uint8_t, uint8_t); // helper for first, next + int findPrev(uint8_t, uint8_t); // helper for last, prev }; #endif // diff --git a/libraries/Set/examples/allTest/allTest.ino b/libraries/Set/examples/allTest/allTest.ino index 686c552d..79888efd 100644 --- a/libraries/Set/examples/allTest/allTest.ino +++ b/libraries/Set/examples/allTest/allTest.ino @@ -186,6 +186,16 @@ void timingTest() } stop = micros(); Serial.println(stop-start); + + Serial.print("last + prev until -1 :\t"); + start = micros(); + n = setA.last(); + while (n != -1) + { + n = setA.prev(); + } + stop = micros(); + Serial.println(stop-start); Serial.println(); Serial.println(); diff --git a/libraries/Set/examples/allTest/reference 0.1.06.txt b/libraries/Set/examples/allTest/reference 0.1.06.txt new file mode 100644 index 00000000..054ece7e --- /dev/null +++ b/libraries/Set/examples/allTest/reference 0.1.06.txt @@ -0,0 +1,87 @@ +Start set_demo : 0.1.06 + +TIMING TEST +clr(): 20 +100x add(): 360 +100x sub(): 360 +100x has(): 380 +100x invert(v): 352 +invert(): 20 +count() empty: 20 +count() full: 168 + +a = b + c: 44 +a = b - c: 56 +a = b * c: 40 +a += b: 32 +a -= b: 32 +a *= b: 32 +a == b: 8 +a != b: 4 +a <= b: 4 + +iteration 10 elements +first: 168 +next: 112 +first + next until -1 : 1052 +last + prev until -1 : 1024 + + +EQUAL TEST +true +false +true +true +1 +equal +true +1 +false +0 + +INTERSECTION TEST +110 +116 +51 + +union test +110 +116 +175 + +diff test +110 +116 +59 + +INTERSECTION2 TEST +110 +116 +51 + +union2 test +110 +116 +175 + +diff2 test +110 +116 +59 + +SUBSET TEST +5 +5 +subset +subset +subset +no subset +no subset +no subset + +ITERATE OVER SET TEST +10 +42 67 77 130 167 200 216 217 241 254 +254 241 217 216 200 167 130 77 67 42 +done... + diff --git a/libraries/Set/examples/allTest/reference 0.1.07.txt b/libraries/Set/examples/allTest/reference 0.1.07.txt new file mode 100644 index 00000000..7aeab57f --- /dev/null +++ b/libraries/Set/examples/allTest/reference 0.1.07.txt @@ -0,0 +1,87 @@ +Start set_demo : 0.1.07 + +TIMING TEST +clr(): 16 +100x add(): 360 +100x sub(): 360 +100x has(): 380 +100x invert(v): 352 +invert(): 20 +count() empty: 20 +count() full: 168 + +a = b + c: 52 +a = b - c: 60 +a = b * c: 40 +a += b: 32 +a -= b: 32 +a *= b: 32 +a == b: 4 +a != b: 4 +a <= b: 4 + +iteration 10 elements +first: 20 +next: 16 +first + next until -1 : 148 +last + prev until -1 : 148 + + +EQUAL TEST +true +false +true +true +1 +equal +true +1 +false +0 + +INTERSECTION TEST +110 +116 +51 + +union test +110 +116 +175 + +diff test +110 +116 +59 + +INTERSECTION2 TEST +110 +116 +51 + +union2 test +110 +116 +175 + +diff2 test +110 +116 +59 + +SUBSET TEST +5 +5 +subset +subset +subset +no subset +no subset +no subset + +ITERATE OVER SET TEST +10 +42 67 77 130 167 200 216 217 241 254 +254 241 217 216 200 167 130 77 67 42 +done... +