hoeken / PsychicHttp

Simple + Robust HTTP/S server with websockets for ESP32 based on ESP-IDF http server.
MIT License
131 stars 27 forks source link

Heap memory testing PsychicHttp vs AsyncWebServer #51

Closed proddy closed 3 months ago

proddy commented 10 months ago

I ran some further benchmarking tests to see why PsychicHttp was using more heap memory than my original build on AsyncWebServer.

What's important to point out here is that my specific AsyncWebServer and AsyncTCP and not the original GitHub versions but very optimized over the years. The stack for example in AsyncTcp is 8192.

I used this repo's benchmark folder for the testing, stripping out everything except adding multiple server.ons() like:

        for (uint8_t i = 0; i < number_uris; i++) {
            char path[10];
            sprintf(path, "/api%d", i);
            server.on(path, HTTP_GET, [](PsychicRequest * request) {
                return request->reply(200, "text/plain", "Hello, World!");
            });
        }

When a URI handler is registered, I see

That would explain with my 80 URI's PsychicHttp uses 12KB more heap memory.

The PsychicHttp code is clean and I don't see any areas for further optimization, so expecting this is all in the IDF.

I'll keep this open for now and report back any further findings.

Chris--A commented 10 months ago

Not really a PsychicHttp thing, but seeing as there is significant String usage, I modified this line:

https://github.com/espressif/arduino-esp32/blob/b2e7338a5e8529b5ede0a8fc7d95703074be093c/cores/esp32/WString.h#L305

To enum { SSOSIZE = 32 };. After testing, heap allocations are basically gone from String usage. For me the few extra stack bytes is worth it.

proddy commented 10 months ago

Thanks @Chris--A - I'll try that out. When I first wrote the first version of my app, many moons ago, it was ESP8266 based I was obsessed with memory optimization and ended up writing my own string class (and later STL classes), after reading so many articles on how 'evil' Arduino's String class was (specially for non-transient operations and data duplication ops like concat()). With ESP32 I'm using std::string with allocated buffers but as you pointed out there are still String's lurking around in other libraries.

Chris--A commented 10 months ago

Thanks @Chris--A - I'll try that out.

Yeah, the ESP8266 and ESP32 versions have been optimized for short strings to avoid allocations. I'm new to the ESP crowd, but have been an AVR/Arduino user for many years, and yes, I would never use String with them and did many safer recreations myself. This is the reason that I do not want to migrate to ArduinoJson 7 either. Sure its nicer, but I would like to grow the stack where I can.

However, I'm trying to use dynamic memory as little as possible so my app can safely run long term. Got an 8MB PSRAM version coming so that will be great.

DaeMonSxy commented 10 months ago
  1. what dou you mean by : "AsyncWebServer and AsyncTCP and not the original GitHub versions but very optimized over the years" ?
  2. I do have a lots of esp-s(8266, esp32 around the house, so I would look forward for a reliable solution to use a crash-proof webserver + async tcp for web-requests. Hence asking, is there any Idea if i would port my code to psychichttp, hot to use a more stable asynctcp-calls together?
hoeken commented 3 months ago

Moving this to discussions