From 0133403e648ce48f08994e4ac42df2557486be84 Mon Sep 17 00:00:00 2001 From: DEvil0000 Date: Sat, 18 Mar 2023 23:08:11 +0100 Subject: [PATCH 1/7] use less stack on number print --- cores/arduino/Print.cpp | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 1e4c99a65..31ae12b48 100644 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -202,22 +202,35 @@ size_t Print::println(const Printable& x) size_t Print::printNumber(unsigned long n, uint8_t base) { - char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. - char *str = &buf[sizeof(buf) - 1]; - - *str = '\0'; + // shortcut printing just 0 prevents later overhead + if (n == 0) { + return write('0'); + } // prevent crash if called with base == 1 if (base < 2) base = 10; - do { - char c = n % base; + unsigned long reverse = 0; + uint8_t digits = 0; + + // reverse the number and count digits + while (n != 0) { + uint8_t remainder = n % base; + reverse = reverse * base + remainder; n /= base; + digits++; + } + + // from here onwards reuse of variable 'n' to count written chars + do { + char c = reverse % base; + reverse /= base; - *--str = c < 10 ? c + '0' : c + 'A' - 10; - } while(n); + c = (c < 10 ? c + '0' : c + 'A' - 10); + n += write(c); + } while(--digits); - return write(str); + return n; } size_t Print::printFloat(double number, uint8_t digits) From e2f54b1a9614d2e6a2bab30757e22273d7f2c5bd Mon Sep 17 00:00:00 2001 From: DEvil0000 Date: Tue, 4 Apr 2023 00:58:41 +0200 Subject: [PATCH 2/7] fixed for 10 digit numbers now working for full long int range --- cores/arduino/Print.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 31ae12b48..dcc7d30aa 100644 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -202,7 +202,7 @@ size_t Print::println(const Printable& x) size_t Print::printNumber(unsigned long n, uint8_t base) { - // shortcut printing just 0 prevents later overhead + // shortcut printing just 0 and prevent later overhead if (n == 0) { return write('0'); } @@ -212,6 +212,10 @@ size_t Print::printNumber(unsigned long n, uint8_t base) unsigned long reverse = 0; uint8_t digits = 0; + char avoid_overflow = n % base; + + // this step and 'avoid_overflow' will make sure it stays in unsigned long range beeing able to print all 10 digits no matter what + n /= base; // reverse the number and count digits while (n != 0) { @@ -222,13 +226,16 @@ size_t Print::printNumber(unsigned long n, uint8_t base) } // from here onwards reuse of variable 'n' to count written chars - do { + while (digits--) { char c = reverse % base; reverse /= base; c = (c < 10 ? c + '0' : c + 'A' - 10); n += write(c); - } while(--digits); + } + + avoid_overflow = (avoid_overflow < 10 ? avoid_overflow + '0' : avoid_overflow + 'A' - 10); + n += write(avoid_overflow); return n; } From 870432ed5a751f213e9e4fcef52e8615a9e3ed22 Mon Sep 17 00:00:00 2001 From: DEvil0000 Date: Tue, 4 Apr 2023 01:00:20 +0200 Subject: [PATCH 3/7] improved on base 2 and base 16 print number implementations added compile flag to disable those additional optimized implementations --- cores/arduino/Print.cpp | 114 ++++++++++++++++++++++++++++++---------- 1 file changed, 87 insertions(+), 27 deletions(-) diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index dcc7d30aa..ed4d13111 100644 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -210,34 +210,94 @@ size_t Print::printNumber(unsigned long n, uint8_t base) // prevent crash if called with base == 1 if (base < 2) base = 10; - unsigned long reverse = 0; - uint8_t digits = 0; - char avoid_overflow = n % base; - - // this step and 'avoid_overflow' will make sure it stays in unsigned long range beeing able to print all 10 digits no matter what - n /= base; - - // reverse the number and count digits - while (n != 0) { - uint8_t remainder = n % base; - reverse = reverse * base + remainder; - n /= base; - digits++; - } - - // from here onwards reuse of variable 'n' to count written chars - while (digits--) { - char c = reverse % base; - reverse /= base; - - c = (c < 10 ? c + '0' : c + 'A' - 10); - n += write(c); +// use -D ARDUINO_PRINT_NUMBER_GENERIC_ONLY when compiling to get only the generic version +#ifndef ARDUINO_PRINT_NUMBER_GENERIC_ONLY + switch (base) { + case 16: + // optimized version for hex prints + { + uint8_t *access = (uint8_t*) &n; + uint8_t written = 0; + for (int8_t i=3; i>=0; i--) { + char c; + c = (access[i] & 0xf0) >> 4; + if (c != 0 || written != 0) { + c = (c < 10 ? c + '0' : c + 'A' - 10); + written += write(c); + } // else: skip leading zeros + c = access[i] & 0x0f; + if (c != 0 || written != 0) { + // skip leading zeros + c = (c < 10 ? c + '0' : c + 'A' - 10); + written += write(c); + } // else: skip leading zeros + } + return written; + } + case 2: + // optimized version for binary prints + { + uint8_t *access = (uint8_t*) &n; + uint8_t written = 0; + for (int8_t i=3; i>=0; i--) { + if (access[i] == 0 && written == 0) { + // skip leading zeros + continue; + } + for (int8_t j=7; j>=0; j--) { + char c; + if (j == 0) { + // avoid shift by 0 - undefined + c = (access[i] & 0x01); + } else { + c = (access[i] & 1<> j; + } + if (c == 0 && written == 0) { + // skip leading zeros + continue; + } + c = (c < 10 ? c + '0' : c + 'A' - 10); + written += write(c); + } + } + return written; + } + default: + // the generic implementation +#endif + { + unsigned long reverse = 0; + uint8_t digits = 0; + char avoid_overflow = n % base; + + // this step and 'avoid_overflow' will make sure it stays in unsigned long range beeing able to print all 10 digits no matter what + n /= base; + + // reverse the number and count digits + while (n != 0) { + uint8_t remainder = n % base; + reverse = reverse * base + remainder; + n /= base; + digits++; + } + + // from here onwards reuse of variable 'n' to count written chars + while (digits--) { + char c = reverse % base; + reverse /= base; + + c = (c < 10 ? c + '0' : c + 'A' - 10); + n += write(c); + } + + avoid_overflow = (avoid_overflow < 10 ? avoid_overflow + '0' : avoid_overflow + 'A' - 10); + n += write(avoid_overflow); + + return n; + } +#ifndef ARDUINO_PRINT_NUMBER_GENERIC_ONLY } - - avoid_overflow = (avoid_overflow < 10 ? avoid_overflow + '0' : avoid_overflow + 'A' - 10); - n += write(avoid_overflow); - - return n; +#endif } size_t Print::printFloat(double number, uint8_t digits) From fd90b4539fc0b0d44a23fe670d19e200bbda9153 Mon Sep 17 00:00:00 2001 From: DEvil0000 Date: Tue, 4 Apr 2023 01:28:44 +0200 Subject: [PATCH 4/7] fixed comment --- cores/arduino/Print.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index ed4d13111..9080ab751 100644 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -227,7 +227,6 @@ size_t Print::printNumber(unsigned long n, uint8_t base) } // else: skip leading zeros c = access[i] & 0x0f; if (c != 0 || written != 0) { - // skip leading zeros c = (c < 10 ? c + '0' : c + 'A' - 10); written += write(c); } // else: skip leading zeros From 66645a2c6022e8f73a0e7f18a28252a42e512b36 Mon Sep 17 00:00:00 2001 From: DEvil0000 Date: Tue, 4 Apr 2023 01:31:54 +0200 Subject: [PATCH 5/7] fixed comment --- cores/arduino/Print.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 9080ab751..cec90dde9 100644 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -269,7 +269,7 @@ size_t Print::printNumber(unsigned long n, uint8_t base) uint8_t digits = 0; char avoid_overflow = n % base; - // this step and 'avoid_overflow' will make sure it stays in unsigned long range beeing able to print all 10 digits no matter what + // this step and 'avoid_overflow' will make sure it stays in unsigned long range being able to print all 10 digits no matter what n /= base; // reverse the number and count digits From e5c727ef6a2cb3e95e9e570d1938636449dec537 Mon Sep 17 00:00:00 2001 From: DEvil0000 Date: Tue, 4 Apr 2023 11:44:32 +0200 Subject: [PATCH 6/7] fixed printNumber base2 and base16 code for -mint8 --- cores/arduino/Print.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index cec90dde9..7db68f48f 100644 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -218,7 +218,7 @@ size_t Print::printNumber(unsigned long n, uint8_t base) { uint8_t *access = (uint8_t*) &n; uint8_t written = 0; - for (int8_t i=3; i>=0; i--) { + for (int8_t i=sizeof(unsigned long)-1; i>=0; i--) { char c; c = (access[i] & 0xf0) >> 4; if (c != 0 || written != 0) { @@ -238,7 +238,7 @@ size_t Print::printNumber(unsigned long n, uint8_t base) { uint8_t *access = (uint8_t*) &n; uint8_t written = 0; - for (int8_t i=3; i>=0; i--) { + for (int8_t i=sizeof(unsigned long)-1; i>=0; i--) { if (access[i] == 0 && written == 0) { // skip leading zeros continue; From a81294fd87572f2f53a52072e971903451afd176 Mon Sep 17 00:00:00 2001 From: DEvil0000 Date: Tue, 4 Apr 2023 19:38:48 +0200 Subject: [PATCH 7/7] avoid writing to base variable so the compiler has a chance of better optimization due to it being basically const then --- cores/arduino/Print.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 7db68f48f..efca8c2be 100644 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -208,7 +208,7 @@ size_t Print::printNumber(unsigned long n, uint8_t base) } // prevent crash if called with base == 1 - if (base < 2) base = 10; + if (base < 2) return printNumber(n, 10); // use -D ARDUINO_PRINT_NUMBER_GENERIC_ONLY when compiling to get only the generic version #ifndef ARDUINO_PRINT_NUMBER_GENERIC_ONLY pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy