Arduino icon indicating copy to clipboard operation
Arduino copied to clipboard

Refactor Web Server Parsing-impl.h using StreamString to avoid String Reallocations

Open Lan-Hekary opened this issue 2 years ago • 8 comments

I was getting many Reallocating large String Warnings when decoding a long URL, and I found that the length of the string is already known before allocating, so it made sense, and it made a big difference.

Lan-Hekary avatar Oct 16 '23 01:10 Lan-Hekary

Should it count % to definitely know the output size? i.e. text.length() - (std::count(text.begin(), text.end(), '%') * 2)

mcspr avatar Oct 16 '23 19:10 mcspr

Hello @mcspr, Thanks for the suggestion, yours is more optimized. I will edit the PR now.

Lan-Hekary avatar Oct 18 '23 15:10 Lan-Hekary

I went into another rabbit hole as I was getting Reallocating large String messages for request arguments and headers. Turns out that there is a pretty neat new interface called StreamString !! I don't know who is responsible for it yet, But kudos !!

The Main culprit in the String Allocations is readStringUntil('\r') because it concatenate the string char by char. Using StreamString still concatenate but in bulk, saving a lot of memory management.

I only made the modification to the webserver, a lot of legacy code in the core that depends on readStringUntil in general can be modified in the same way. I am waiting on your inputs and if you want me to continue with this refactoring. Thanks.

Lan-Hekary avatar Oct 19 '23 19:10 Lan-Hekary

I am waiting on your inputs and if you want me to continue with this refactoring.

Please go ahead, and thanks !

d-a-v avatar Nov 04 '23 22:11 d-a-v

Given #9011, would you think having sendUntil(to, untilString) would help ?

d-a-v avatar Nov 07 '23 13:11 d-a-v

@d-a-v Yes, think it would help too much. Right now I use client.sendUntil(req, '\r'); to send the string minus the carriage return character then client.readStringUntil('\n'); to dummy read the new line character. If I can use a string terminator "\r\n" this would further simplify the call to only one. But I fear it may introduce some complexity in the processing that defeat the purpose of the refactoring. Character comparison is faster than string comparison. and in case of HTTP Protocol you can always expect \r\n, so I guess it's better from performance standpoint to use Character comparison.

Upon further look of #9011 the implementation is based on character comparison, and I think it would not hurt performance. if we can do the same in sendUntil it would help.

Lan-Hekary avatar Nov 08 '23 13:11 Lan-Hekary

if we can do the same in sendUntil it would help.

Right. It was made from readStringUntil so the same api extension would indeed be interesting.

d-a-v avatar Nov 17 '23 22:11 d-a-v

Hello @d-a-v , I tried to implement the same API for StreamStrings and then Return String at the end. Please take a look at my attempt, it's still under test, I did some testing and so far it's working, I am afraid if there is any edge case I missed, so help me to test if you can. I am waiting on your feed back, then I will clean the code up for merge if you approve.

Lan-Hekary avatar Nov 18 '23 05:11 Lan-Hekary