Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unwanted code size increase in v2.7.0 because of String constants #989

Closed
s-hadinger opened this issue Nov 3, 2019 · 7 comments · Fixed by #992
Closed

Unwanted code size increase in v2.7.0 because of String constants #989

s-hadinger opened this issue Nov 3, 2019 · 7 comments · Fixed by #992

Comments

@s-hadinger
Copy link
Contributor

Hi David, great lib!

When upgrading Tasmota with IRremoteESP8266 v2.7.0, we saw a code increase of 3.8KB in Flash size.

Digging into it, the code increase came from IRtext.cpp creating a log of String objects that were actually not used in the Tasmota build. A quick fix disables the Strings when we are compiling standard Tasmota.

https://github.com/arendst/Tasmota/blob/development/lib/IRremoteESP8266-2.7.0/src/IRtext.cpp

I would advise against using String for constants because of the following:

  • Since c++ objects can have side-effects, String objects cannot be removed by the linker even if they are not used elsewhere in the code.
  • The static code generated by the compiler for allocating and deallocating all the String objects is big: 2.0KB
  • The string literals are not in PROGMEM, so they are already taking 1.5KB of RAM (and of Flash). Worse, the String objects reallocate the same strings in their own memory structures, meaning at least an additional 1.5KB of RAM spent.

Actually it would be probably more compact to just use char* literals instead of String objects.

Happy to discuss about alternatives.

Version/revision of the library used

v2.7.0 in Tasmota

@crankyoldgit
Copy link
Owner

Bugger! That behaviour didn't show up in my testing. My testing had the overall size go down albeit for code that was using said strings etc.

Happy to discuss about alternatives.

Please!

I'd really like to avoid c-style string handling as the memory allocation/handling is a nightmare.

I tried putting the strings in PROGMEM, but everything blew up. Any guidance you've got for successfully doing that is more than welcome.

Actually it would be probably more compact to just use char* literals instead of String objects.

Reducing the duplication of string literals was actually smaller. A 1.5k reduction in the binary size. I was surprised myself.

No argument that storing the strings as char * variable would reduce size/overhead compared to String instances. Defining them as const also caused the compiler to not even include them in the IRtext.o and thus caused it link failures.

Again, I'm open to all suggestions to reduce the overhead. How does Tasmota handle the string concatenation memory allocation issues etc?

Also, do you have a link to your analysis notes at all? I'm interested in your findings and how to replicate them. i.e. Teach me! :)

@crankyoldgit crankyoldgit self-assigned this Nov 4, 2019
crankyoldgit added a commit that referenced this issue Nov 11, 2019
* Use PROGMEM for c_str's as well.
* Reduces flash binary size.
  o IRrecvDumpV2: ~1kb saved.
  o IRMQTTServer: ~2.7kb saved.

Testing:
* Passes existing all unit tests.
* IRrecvDumpV2: Run on a NodeMCU board. Decodes Kelvinator A/C remote as 
before.
* IRMQTTServer: Run on a NodeMCU board. Web interface checked. Didn't 
crash.

For #989
FYI @s-hadinger
@crankyoldgit
Copy link
Owner

crankyoldgit commented Nov 11, 2019

@s-hadinger Can you please download and checkout the #992 / https://github.com/crankyoldgit/IRremoteESP8266/tree/strings branch and let me know how it performs memory-wise with Tasmota etc.

@s-hadinger
Copy link
Contributor Author

Thanks, will do now.

@s-hadinger
Copy link
Contributor Author

s-hadinger commented Nov 11, 2019

Good news. For the minimal IR support in Tasmota standard, there is no change compared to the patched IRtext.cpp. The unwanted code flash increase is gone.

For the version of Tasmota with full IR support, I do see a Flash/Ram size reduction:
-1.5K of Memory, -2.7K of Flash

v2.7.0:
DATA: [====== ] 62.4% (used 51120 bytes from 81920 bytes)
PROGRAM: [====== ] 63.7% (used 651817 bytes from 1023984 bytes)

strings branch:
DATA: [====== ] 60.6% (used 49652 bytes from 81920 bytes)
PROGRAM: [====== ] 63.4% (used 649093 bytes from 1023984 bytes)

@crankyoldgit
Copy link
Owner

Excellent. I'll merge and close this issue. Thanks for confirming.

crankyoldgit added a commit that referenced this issue Nov 11, 2019
* Use `char*` instead of `String` for common text.
* Use PROGMEM for c_str's as well.
* Reduces flash binary size.
  o IRrecvDumpV2: ~1kb saved.
  o IRMQTTServer: ~2.7kb saved.

Testing:
* Passes existing all unit tests.
* IRrecvDumpV2: Run on a NodeMCU board. Decodes Kelvinator A/C remote as 
before.
* IRMQTTServer: Run on a NodeMCU board. Web interface checked. Didn't 
crash.

Fixes #989
crankyoldgit added a commit that referenced this issue Nov 25, 2019
_v2.7.1 (20191125)_

**[Bug Fixes]**
- Hitachi424Ac: Fix Incorrect Power Byte Values (#987)
- Coolix: Fix setPower(false) issue. (#990)

**[Features]**
- Use `char*` instead of `String` for common text. Saves ~1-3k. (#992, #989)
- Hitachi424Ac: Add Vertical Swing ability (#986)

**[Misc]**
- IRMQTTServer: Update HA example/discovery message. (#995)
- Move newly added common text to a better location. (#993)
crankyoldgit added a commit that referenced this issue Nov 25, 2019
_v2.7.1 (20191125)_

**[Bug Fixes]**
- Hitachi424Ac: Fix Incorrect Power Byte Values (#987)
- Coolix: Fix setPower(false) issue. (#990)

**[Features]**
- Use `char*` instead of `String` for common text. Saves ~1-3k. (#992, #989)
- Hitachi424Ac: Add Vertical Swing ability (#986)

**[Misc]**
- IRMQTTServer: Update HA example/discovery message. (#995)
- Move newly added common text to a better location. (#993)
@crankyoldgit
Copy link
Owner

FYI, this has been included in the just released version 2.7.1 of the library.

@s-hadinger
Copy link
Contributor Author

Thanks David. I will update Tasmota.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants