Deleting multiple children is slow due to eager layout updates #4908
Closed
Description
Perform all steps below and tick them with [x]
- Read the FAQ
- Check the related part of the Documentation
- Update lvgl to the latest version
- Reproduce the issue in a Simulator
Describe the bug
lv_obj_del()
eagerly calls lv_obj_update_layout()
:
Line 79 in d442740
This was introduced in #3210.
Eagerly updating the layout can be very expensive when deleting many children of an object. lv_obj_clean()
does not have the same problem, but not always all children have to be deleted.
To Reproduce
Run the following example for results like:
0 ms for 1 labels
0 ms for 10 labels
3 ms for 100 labels
229 ms for 1000 labels
18168 ms for 10000 labels
Note that these numbers were created on a relatively powerful desktop machine. On low powered devices there's a noticable delay even for moderate numbers of deleted objects.
#include "lvgl.h"
#include <unistd.h>
#include <time.h>
#include <stdio.h>
static uint32_t tick_cb()
{
struct timespec ts = { 0 };
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec * 1000 + ts.tv_nsec / 1000 / 1000;
}
static void repro(unsigned int num_children)
{
lv_obj_t * screen = lv_obj_create(NULL);
lv_obj_set_flex_flow(screen, LV_FLEX_FLOW_COLUMN);
lv_obj_t * label[num_children];
// Create many children
for(unsigned int i = 0; i < num_children; i++) {
label[i] = lv_label_create(screen);
lv_label_set_text_fmt(label[i], "Label %d", i);
}
lv_display_load_scr(screen);
// Delete some of them
uint32_t begin = tick_cb();
for(unsigned int i = 0; i < num_children; i++) {
if(i % 10 != 0) {
lv_obj_del(label[i]);
}
}
uint32_t end = tick_cb();
printf("%u ms for %u labels\n", end - begin, num_children);
}
int main()
{
lv_init();
lv_tick_set_cb(tick_cb);
lv_sdl_window_create(1024, 600);
repro(1);
repro(10);
repro(100);
repro(1000);
repro(10000);
while(true) {
uint32_t delay = lv_timer_handler();
usleep(delay * 1000);
}
return 0;
}
Expected behavior
Better practical performance (even if complexity remains quadratic).
Metadata
Assignees
Labels
No labels