After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 324724 - o(n^2) slowdown in e_cal_backend_cache_get_components
o(n^2) slowdown in e_cal_backend_cache_get_components
Status: RESOLVED FIXED
Product: evolution-data-server
Classification: Platform
Component: Calendar
1.6.x (obsolete)
Other Linux
: Normal critical
: ---
Assigned To: Harish Krishnaswamy
Evolution QA team
Depends on:
Blocks: 327516
 
 
Reported: 2005-12-21 18:53 UTC by Dave Malcolm
Modified: 2013-09-14 16:49 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Dave Malcolm 2005-12-21 18:53:53 UTC
Subscribe to this webcal:
webcal://ical.mac.com/ical/DVDs.ics

(this is the torture test I use for the ical code)

CPU load goes up to 100% and Evolution UI stops refreshing.

On repeatedly breaking into the e-d-s process, there seems to be a slow loop here:
  • #0 IA__g_list_last
    at glist.c line 450
  • #1 IA__g_list_append
    at glist.c line 73
  • #2 e_cal_backend_cache_get_components
    at e-cal-backend-cache.c line 439
  • #3 e_cal_backend_http_start_query
    at e-cal-backend-http.c line 797
  • #4 e_cal_backend_start_query
    at e-cal-backend.c line 691
  • #5 impl_EDataCalView_start
    at e-data-cal-view.c line 255
  • #6 _ORBIT_skel_small_GNOME_Evolution_Calendar_CalView_start
    at Evolution-DataServer-Calendar-common.c line 16
  • #7 ORBit_POA_setup_root
    from /usr/lib/libORBit-2.so.0
  • #8 ORBit_OAObject_invoke
    from /usr/lib/libORBit-2.so.0
  • #9 ORBit_small_invoke_adaptor
    from /usr/lib/libORBit-2.so.0
  • #10 ORBit_POAObject_post_invoke
    from /usr/lib/libORBit-2.so.0
  • #11 ORBit_POAObject_post_invoke
    from /usr/lib/libORBit-2.so.0
  • #12 giop_thread_queue_process
    from /usr/lib/libORBit-2.so.0
  • #13 giop_thread_queue_process
    from /usr/lib/libORBit-2.so.0
  • #14 link_servers_move_io_T
    from /usr/lib/libORBit-2.so.0
  • #15 IA__g_main_context_dispatch
    at gmain.c line 1913
  • #16 g_main_context_iterate
    at gmain.c line 2544
  • #17 IA__g_main_loop_run
    at gmain.c line 2748
  • #18 bonobo_main
    from /usr/lib/libbonobo-2.so.0
  • #19 main
    at server.c line 354
  • #20 __libc_start_main
    from /lib/libc.so.6
  • #21 _start

It's building a long g_list by repeatedly appending to the end; this is O(n^2) behaviour:

(gdb) print list->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next
$24 = (GList *) 0x94b9ce8

(yes, it's a long list).

Looks like the function needs an end-of-list temporary to optimize the construction of the "list" local
Comment 1 Chenthill P 2006-02-10 05:33:50 UTC
To add to the above reasons, the main reason for 100% cpu is that, the ical object is parsed from the ical string every time.  All the ical objects are hashed based on the uid as a key and ical string as a value. So a search expression which queries for appointments between a <start date> to a <end date> will have to get all the ical strings, parse them to check if it matches the search expression. If there are very large number of appointments as in this case, the cpu raises to 100%. This should be optimized.
Comment 2 Harish Krishnaswamy 2006-02-10 09:54:54 UTC
Dave, Thanks for pointing that out. A prize catch :-).
Now that I am looking at this I might as well take a closer look at the cache search logic and see if we can tame the beast better.
Comment 3 André Klapper 2006-04-28 23:05:35 UTC
hmm... harish, are there any news on this?
Comment 4 André Klapper 2006-06-15 13:30:42 UTC
removing old target milestone
Comment 5 Harish Krishnaswamy 2006-07-03 17:00:51 UTC
Duh..The patch addressing the above g_list_append evil as well as the usage of xx_get_components in the backends has been rotting on my patch queue for ages now..thanks for the wake-up call :-)
Testing this and committing this for the 1.7.4 release.
Comment 6 Harish Krishnaswamy 2006-07-10 11:05:25 UTC
well - i am not done testing on revamping the cache usage - but realize albeit late that the O(n^2) could have been addressed with a 2 line change..committed the same.
Comment 7 André Klapper 2006-07-10 12:22:57 UTC
harish: thanks for looking into this! :-)

http://cvs.gnome.org/viewcvs/evolution-data-server/calendar/libedata-cal/e-cal-backend-cache.c?r1=1.28&r2=1.29
(adding diff link here just for tracking, because changelog entry did not include the bug id.)