I gave this a second thought. lv_btnmatrix_set_map() gets called quite often, actually, this is even documented in the comment above:
* lv_btnmatrix_set_map is called on receipt of signals such as
* LV_SIGNAL_CORD_CHG regardless of whether the map has changed (e.g.
* calling lv_obj_align on the map will trigger this).
So, omitting the test and performing the reallocation unconditionally results in performance penalty. Maybe not severe, but entirely unnecessary, as in probably vast majority of cases, maps won’t change ever during lifetime of the btnm.
Actually, the comment contains the suggested solution:
* TODO: separate all map set/allocation from layout code below and skip
* set/allocation when map hasn't changed.
As it’s probably late now to do this without breaking existing code, I would add a flag to the btnm ext struct, indicating whether reallocation shall be forced or not. I would let the user choose which one model to use, by adding a second stub _create() which would clear the force-realloc flag along with creation of the map. I would then use the flag in set_map(), and would also expose interface to the manual reallocation function for those, who choose not to force reallocation. Maybe some other widgets making use of btnm might be reviewed to use the non-forced version. Plus documentation of course, pointing out the history and reasons for this solution.
Just my 2 eurocents.