-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Print::print(const __FlashStringHelper *) is very inefficient #6524
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
Comments
A PR for this would be quite welcome. Just make sure the buffer isn't too large, as the stack space is pretty limited on this device. I think 64 bytes or so is what is used elsewhere. |
I was looking into the code to see if this suggested change could also benefit my own code. But what I don't understand is how it could be faster to use Arduino/cores/esp8266/pgmspace.cpp Lines 151 to 172 in 74819a7
Not sure if the code has changed, as it appears to be some external code now? |
I didn't realise none of the implementations were efficient :( It would still be faster to use |
Try with nagle / without |
@TD-er , that's a very old version. The newlib-xtensa ones are significantly optimized and pretty close to RAM ones when possible: https://github.com./earlephilhower/newlib-xtensa/blob/xtensa-2_2_0-lock-arduino/newlib/libc/sys/xtensa/string_pgmspace.c. In any case, larger chunks would be faster due to lower overhead. PRs always appreciated. :) |
|
You do want do call it because it forces data out, per arduino API. And this is the way And |
Look at the ESP32 implementation if you don't believe that it gets implemented as flushing input.
|
Quoting
Quoting
While it is unclear what buffer it is about, In official arduino avr implementation, About esp32 implementation, I don't agree with it, and comments state that we have the good implementation. @me-no-dev might have more insights about that. I think this is an inheritance from Arduino 1.0.
Well then. We can speak for hours, or you can just try whether |
@earlephilhower @d-a-v what is the status here? is there anything to improve, or is the current code already reasonable? |
@devyte The function still needs to be modified to write in blocks of 64 bytes. It's not something I'm likely to get around to doing because I've implemented a general outgoing buffer in my application so that separate print calls can be merged too. |
@devyte current code is functionally correct, but does only 1 byte-sized writes when it could potentially be doing larger chunks. That's an optimization, yes, but not critical. If there's downtime it's worth doing, but it's not a high priority IMO. |
Fixes esp8266#6524 Should help with speed of output when printing large flash strings to things like a file or a TCP connection. Use a 128 byte chunk in a temp buffer to send data using write(), reducing the # of write calls by ~128x.
The implementation calls
pgm_read_byte()
to read every character. This is inefficient because it will read every block of 4 bytes multiple times.It calls calls
write(c)
for every character. This is very inefficient at the network level ifTCP_NODELAY
is turned on because suddenly all flash strings are sent out as one byte per packet.It should use
strncpy_P()
with a small buffer instead.The text was updated successfully, but these errors were encountered: