-
-
Notifications
You must be signed in to change notification settings - Fork 179
Map to vector #37
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
Map to vector #37
Conversation
…24 bytes of heap for a small device (LYWSD03MMC)
…teristicVector instead) saving in total (compared to the current master) 1,508 bytes of program memory and 6,500 bytes of heap for a small device (LYWSD03MMC)
@h2zero Nice! The std::string key duplication in the std::map annoyed me lot!! I love your library, but I need to get it smaller, because I want to combine BLE devices with other (Serial) devices. I will checkout the |
My thoughts are we could maintain backward compatible API while using a vector internally and dynamically create the map(s) if the user wants them, just created in the function call from the vector instead. |
That is possible for sure, but is it worth the effort? A novice user will not need it, and a more experienced user can live with it, I think. |
I took a quick look at the differences here at github. I am not very familiar with semaphores (but I am very charmed about the use in asynchronous calls that I saw in this library), so I do not really grasp the benefits. What are he benefits? Are these changes already in master? If not: any plans to integrate these? |
The changes there reduce the memory usage by ~200 or so bytes per service/characteristic/descriptor, yes this will be integrated once I'm satisfied with it. |
So that is ~200 bytes on top of the map to vector change? Because I just checked and in the oter branch still a map is used. That is another huge improvement! |
Yes, the old |
Updated NimBLEScan to use a |
Good stuff, I'll add in the peripheral related changes. I think I will wait on breaking compatibility until there is a release version that maintains it for those who just want to keep changes minimal. After that, this change as well as many others will be done. Sound good? |
Thnx @h2zero! I would like the changes to be released soon, if possible. Breaking changes are in a release usually, but these are the reasons why I think it can be done now:
On top of that, I think the functions to get the maps shouldn't be there at all. The maps (and for that purpose also the vectors) are there to set up an internal structure, and are nicely encapsulated by the get-by-UUID functions. Instead an iterator could be defined, returning Last but not least, I need the changes and rather want them in the official library than in a fork or a branch. Another thing, if anybody really wants the map, it can be easily created by the user from the vector. |
@Jeroen88 Sorry for the delay in response, I wanted to take some time to consider your argument. Reason being, I know of a couple projects that use this code, but on the other hand changing the app code won't be that big of a chore for those. It was always my vision to remain compatible as much as possible for a proper comparison of the benefits as a nearly plug and play library (this all started as an experiment after all). However there are quite a few shortcomings in the original code and I need to change my thoughts for the betterment of all users. On that note I will start on the incorporation of this PR and add the server related changes to it. Thank you again for all your efforts, they are very much appreciated 😄. |
@Jeroen88 I was just testing this with a peripheral that has 10 uuids, saved 1080 bytes of memory. Then I merged the freeRTOS-rework branch and saved an additional 1630 bytes. I can see if you're connecting to a device with 72 uuid's that would be an incredible difference. I have to wonder what they were thinking when making such a device 🤯 . |
Thnx @h2zero for making me happy! In my opinion the original library did a very good job in designing a framework with the device, client, server, (remote) service, (remote) characteristic and (remote) descriptor. I think the designer may have had neat code in mind at first, like service['... uuid ... '], but it didn't work out that way. Now the map is a real waste of memory! Still, I like the original design. Your work made the library fit in my use case, thnx for that again! I'll add a small commit to this PR, possibly today, I think it would be nice to find an advertised device by it's address. |
@Jeroen88 If you're just looking to connect to a device directly by address you can do this already with |
@h2zero Thanks, but no, I am looking for the service data of a scanned device |
I'm confused,
I'm surprised that it would even compile? |
No I was not clear, I am working on a getDevice() taking an address as parameter, but ran into the bug described in PR #45, so I had to fix that first. |
@Jeroen88 that makes more sense. I just pushed a new branch |
@h2zero I did the test, your guessing was close :D Sketch used for testing:
Results on current master
Results on branch single-semaphore-test
The device is a MJ-HT-V1 temperature / humidity sensor. This is it's string representation:
Conclusion: And the savings from map to vector still to be added on top of this! |
Nice! Don't get too comfortable with that branch, it was for experimental purposes and won't work in a few scenarios (semaphore lockups). Good to see the heap savings, I'm going to implement the semaphores dynamically instead, might add a bit of overhead and program size but totally worth it to save that heap space. |
Very nice indeed! |
Closing this as #46 was merged. Thanks again! |
In the first commit: exchange the
<std::map>
's holding the children of an object for<std::vector>
's, saving 1,076 bytes of program memory and 5,024 bytes of heap for a small device (LYWSD03MMC).In the second commit: removing the std::map m_characteristicMapByHandle completely from the library (using the handles from m_characteristicVector instead) saving in total (including the first commit) 1,508 bytes of program memory and 6,500 bytes of heap for a small device (LYWSD03MMC).
The heap memory saving is dependent of the device: the more complex the device (more service, characteristic and descriptor UUID's) the larger the saving (and vice versa).
For the LYWSD03MMC
pClient->toString()
is compared between the original library and this commit. They are (and should be) equal.A small drawback is the API change,
getServices()
,getDescriptors()
,getCharacteristics()
return a<std::vector>
now instead of a<std::map>
, andgetCharacteristicsByHandle()
is completely removed, but the notable program and heap memory increase are worth it IMHO.@h2zero for your convenience I left the original code in, commenting it out, for easier comparison. Let me know if you need a 'clean' PR.