diff options
author | Michael Manganiello <adamantike@users.noreply.github.com> | 2022-03-21 23:06:27 -0300 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-04-20 18:37:56 +0200 |
commit | 56081cdb6eb6afbefe520797503525d6a978952c (patch) | |
tree | 76e82b23a86c8d2f48d1f9ed44675b377ab5e49a /Userland/Libraries/LibGUI | |
parent | 3afce86e8356d397d19d43845dfcd6cb66dac761 (diff) | |
download | serenity-56081cdb6eb6afbefe520797503525d6a978952c.zip |
LibGUI: Remove Tile.date_time member from Calendar
Currently, navigating through different years in the Year view of the
Calendar app or the taskbar is very slow.
Profiling results show that almost all the time is spent in
`Calendar::update_tiles`, and specifically, in `DateTime::create` and
`DateTime::set_time`.
Performance can improve substantially if the `TZ` environment variable
is set [0], but we can improve the current code to perform better
nevertheless :^)
This diff focuses on removing the need of the `Tile` struct to require
the instantiation of a `DateTime` object, which avoids _at least_ 365
object instantiations in the Year view, on each `update_tiles` call.
Instead, as the `date_time` isn't used often, we can instantiate it on
demand when a particular date is selected.
[0] https://blog.packagecloud.io/set-environment-variable-save-thousands-of-system-calls/
Diffstat (limited to 'Userland/Libraries/LibGUI')
-rw-r--r-- | Userland/Libraries/LibGUI/Calendar.cpp | 61 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/Calendar.h | 4 |
2 files changed, 34 insertions, 31 deletions
diff --git a/Userland/Libraries/LibGUI/Calendar.cpp b/Userland/Libraries/LibGUI/Calendar.cpp index 772f9513e4..a1f35e5ee9 100644 --- a/Userland/Libraries/LibGUI/Calendar.cpp +++ b/Userland/Libraries/LibGUI/Calendar.cpp @@ -264,49 +264,50 @@ void Calendar::update_tiles(unsigned view_year, unsigned view_month) { set_view_date(view_year, view_month); - unsigned months; - mode() == Month ? months = 1 : months = 12; + auto now = Core::DateTime::now(); + unsigned months = mode() == Month ? 1 : 12; for (unsigned i = 0; i < months; i++) { if (mode() == Year) view_month = i + 1; + + auto first_day_of_current_month = Core::DateTime::create(view_year, view_month, 1); + unsigned start_of_month = first_day_of_current_month.weekday(); + unsigned days_from_previous_month_to_show = start_of_month == 0 ? 7 : start_of_month; + for (unsigned j = 0; j < 42; j++) { - auto date_time = Core::DateTime::create(view_year, view_month, 1); - unsigned start_of_month = date_time.weekday(); unsigned year; unsigned month; unsigned day; - if (start_of_month == 0 && mode() != Year) { + if (j + 1 <= days_from_previous_month_to_show) { + // Day from previous month. month = (view_month - 1 == 0) ? 12 : view_month - 1; year = (month == 12) ? view_year - 1 : view_year; - date_time.set_time(year, month, 1); - day = (date_time.days_in_month() - 6 + j); - } else if (start_of_month > j) { - month = (view_month - 1 == 0) ? 12 : view_month - 1; - year = (month == 12) ? view_year - 1 : view_year; - date_time.set_time(year, month, 1); - day = (date_time.days_in_month() - (start_of_month) + j) + 1; - } else if ((j - start_of_month) + 1 > date_time.days_in_month()) { + day = days_in_month(year, month) + j + 1 - days_from_previous_month_to_show; + } else if (j + 1 > days_from_previous_month_to_show + first_day_of_current_month.days_in_month()) { + // Day from next month. month = (view_month + 1) > 12 ? 1 : view_month + 1; year = (month == 1) ? view_year + 1 : view_year; - day = ((j - start_of_month) + 1) - date_time.days_in_month(); + day = j + 1 - days_from_previous_month_to_show - first_day_of_current_month.days_in_month(); } else { + // Day from current month. month = view_month; year = view_year; - day = (j - start_of_month) + 1; + day = j + 1 - days_from_previous_month_to_show; } - date_time.set_time(year, month, day); - - m_tiles[i][j].date_time = date_time; - m_tiles[i][j].is_outside_selected_month = (date_time.month() != view_month - || date_time.year() != view_year); - m_tiles[i][j].is_selected = (date_time.year() == m_selected_date.year() - && date_time.month() == m_selected_date.month() - && date_time.day() == m_selected_date.day() + + m_tiles[i][j].year = year; + m_tiles[i][j].month = month; + m_tiles[i][j].day = day; + m_tiles[i][j].is_outside_selected_month = (month != view_month + || year != view_year); + m_tiles[i][j].is_selected = (year == m_selected_date.year() + && month == m_selected_date.month() + && day == m_selected_date.day() && (mode() == Year ? !m_tiles[i][j].is_outside_selected_month : true)); - m_tiles[i][j].is_today = (date_time.day() == Core::DateTime::now().day() - && date_time.month() == Core::DateTime::now().month() - && date_time.year() == Core::DateTime::now().year()); + m_tiles[i][j].is_today = (day == now.day() + && month == now.month() + && year == now.year()); } } update(); @@ -472,7 +473,7 @@ void Calendar::paint_event(GUI::PaintEvent& event) text_rect = Gfx::IntRect(tile_rect); } - auto display_date = String::number(m_tiles[0][i].date_time.day()); + auto display_date = String::number(m_tiles[0][i].day); if (m_tiles[0][i].is_selected && (width < 30 || height < 30)) painter.draw_rect(tile_rect, palette().base_text()); @@ -581,7 +582,7 @@ void Calendar::paint_event(GUI::PaintEvent& event) set_font(small_font); } - auto display_date = String::number(m_tiles[l][i].date_time.day()); + auto display_date = String::number(m_tiles[l][i].day); if (m_tiles[l][i].is_selected) painter.draw_rect(tile_rect, palette().base_text()); @@ -687,7 +688,7 @@ void Calendar::mouseup_event(GUI::MouseEvent& event) continue; if (m_tiles[i][j].rect.contains(event.position())) { m_previous_selected_date = m_selected_date; - m_selected_date = m_tiles[i][j].date_time; + m_selected_date = Core::DateTime::create(m_tiles[i][j].year, m_tiles[i][j].month, m_tiles[i][j].day); update_tiles(m_selected_date.year(), m_selected_date.month()); if (on_tile_click) on_tile_click(); @@ -723,7 +724,7 @@ void Calendar::doubleclick_event(GUI::MouseEvent& event) mode() == Month ? months = 1 : months = 12; for (int i = 0; i < months; i++) { for (int j = 0; j < 42; j++) { - if (m_tiles[i][j].date_time.day() != m_previous_selected_date.day()) + if (m_tiles[i][j].day != m_previous_selected_date.day()) continue; if (mode() == Year && m_tiles[i][j].is_outside_selected_month) continue; diff --git a/Userland/Libraries/LibGUI/Calendar.h b/Userland/Libraries/LibGUI/Calendar.h index 72d653fc6e..4a0b4f77a5 100644 --- a/Userland/Libraries/LibGUI/Calendar.h +++ b/Userland/Libraries/LibGUI/Calendar.h @@ -101,7 +101,9 @@ private: Vector<MonthTile> m_months; struct Tile { - Core::DateTime date_time; + unsigned year; + unsigned month; + unsigned day; Gfx::IntRect rect; int width { 0 }; int height { 0 }; |