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 682903 - Use gee’s MultiMap iterators
Use gee’s MultiMap iterators
Status: RESOLVED OBSOLETE
Product: folks
Classification: Platform
Component: general
git master
Other All
: Normal normal
: Unset
Assigned To: folks-maint
folks-maint
Depends on: 675067
Blocks:
 
 
Reported: 2012-08-28 21:28 UTC by Philip Withnall
Modified: 2018-08-04 08:34 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Mostly avoid an expensive multi-map iteration pattern (20.16 KB, patch)
2013-03-07 18:16 UTC, Simon McVittie
committed Details | Review

Description Philip Withnall 2012-08-28 21:28:20 UTC
Courtesy of bug #675067, libgee (0.8!) has gained MultiMap iterator support. We should use these, since they should be a lot more efficient for iterating over MultiMaps than the previous technique of iterating over get_keys() and calling get_values() for each of them.
Comment 1 Simon McVittie 2013-03-07 18:16:15 UTC
Created attachment 238328 [details] [review]
Mostly avoid an expensive multi-map iteration pattern

If you have a MultiMap with, say, 100 keys each with 1 value, and you
iterate over it like this (pseudocode):

    for key in keys():
        values = get(key)
        for value in values:
            do something(key, value)

then you have constructed one GObject for the result of keys(), and
100 GObjects for the results of get() (because it returns a read-only
view). If you iterate it like this:

    iter = map_iterator()
    while iter.next():
        do something(iter.key(), iter.value())

there's only one extraneous GObject, the iterator itself.

When there are thousands of contacts, as in add-contacts-stress-test,
this really starts to matter.

This patch doesn't fix every use of get_keys() - some of them do
non-trivial work per key as well as per value, making it awkward to
convert to map_iterator() - but it's a start. It cuts 'user' CPU time
for IndividualAggregator quiescence for an e-d-s Google account with
2049 contacts (reading from cache) by around 3%.
Comment 2 Philip Withnall 2013-03-07 19:41:14 UTC
Review of attachment 238328 [details] [review]:

Perhaps it would be worthwhile adding this to HACKING under the ‘Coding style’ section? Something along the lines of “always explicitly use an iter when iterating over Maps and MultiMaps for efficiency reasons”.

Apart from that, this looks great! Please commit to master with the above change to HACKING. Thanks.
Comment 3 Simon McVittie 2013-03-08 14:05:14 UTC
Comment on attachment 238328 [details] [review]
Mostly avoid an expensive multi-map iteration pattern

Pushed as 3ead5929, thanks.

Leaving this bug open, because there's more that could be done.
Comment 4 Simon McVittie 2013-03-08 14:08:19 UTC
(In reply to comment #2)
> Perhaps it would be worthwhile adding this to HACKING under the ‘Coding style’
> section?

I gave this advice for multimaps. I don't think there's nearly as much performance advantage in avoiding get_keys() + get() for ordinary 1:1 maps (OK, get_keys() + iterating over them creates two GObjects rather than one, but that's still O(1) so it doesn't really show up in my profiling).
Comment 5 Philip Withnall 2013-03-08 19:25:09 UTC
(In reply to comment #4)
> (In reply to comment #2)
> > Perhaps it would be worthwhile adding this to HACKING under the ‘Coding style’
> > section?
> 
> I gave this advice for multimaps. I don't think there's nearly as much
> performance advantage in avoiding get_keys() + get() for ordinary 1:1 maps (OK,
> get_keys() + iterating over them creates two GObjects rather than one, but
> that's still O(1) so it doesn't really show up in my profiling).

IIRC it’s (slightly) more efficient in CPU time for Maps since calling get() has to skip over empty and collided buckets multiple times; whereas the Iterator can keep state to avoid them after skipping them the first time.
Comment 6 GNOME Infrastructure Team 2018-08-04 08:34:31 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/folks/issues/42.