Skip to content

Commit 6c423bc

Browse files
committed
Caja-icon-info: Optimize icon lookups by GIcon.
The caja_icon_info_lookup method was potentially doing multiple icon lookups for a single icon, as well as triggering an additional fallback lookup when returning an empty (no pixbuf) CajaIconInfo to CajaFile. This streamlines and simplifies the lookup process. The hash table lookup always occurs first, before any Gtk icon cache lookup is made (these are expensive, according to perf analysis,) and a returned icon info will *always* be added to a hash table, potentially already containing a fallback icon. GIcons stringify well enough to use the strings exclusively for hash keys. This eliminates the extra cost of looking up filenames from the Gtk icon cache. Ported from github.com/linuxmint/nemo/commit/98843e26b48cd3526cacfe90cfa4ba201d1f3aee where this benchmark resulted for Nemo: .# sync; echo 3 > /proc/sys/vm/drop_caches mtwebster:~/bin/nemo[master]> NEMO_BENCHMARK_LOADING=1 nemo /usr/bin with: Nemo startup time: 2.011817 seconds Folder load time: 1.158854 seconds Idle...Folder load time: 1.226699 seconds without: Nemo startup time: 2.464361 seconds Folder load time: 1.591494 seconds Idle...Folder load time: 1.692273 seconds
1 parent 021ff2a commit 6c423bc

File tree

2 files changed

+74
-149
lines changed

2 files changed

+74
-149
lines changed

libcaja-private/caja-file.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4517,13 +4517,15 @@ caja_file_get_icon (CajaFile *file,
45174517
return icon;
45184518
}
45194519

4520-
if (flags & CAJA_FILE_ICON_FLAGS_FORCE_THUMBNAIL_SIZE) {
4521-
modified_size = size * scale;
4522-
} else {
4523-
modified_size = size * scale * cached_thumbnail_size / CAJA_ICON_SIZE_STANDARD;
4524-
}
45254520
if (flags & CAJA_FILE_ICON_FLAGS_USE_THUMBNAILS &&
45264521
caja_file_should_show_thumbnail (file)) {
4522+
4523+
if (flags & CAJA_FILE_ICON_FLAGS_FORCE_THUMBNAIL_SIZE) {
4524+
modified_size = size * scale;
4525+
} else {
4526+
modified_size = size * scale * cached_thumbnail_size / CAJA_ICON_SIZE_STANDARD;
4527+
}
4528+
45274529
if (file->details->thumbnail) {
45284530
int w, h, s;
45294531
double thumb_scale;
@@ -4595,10 +4597,6 @@ caja_file_get_icon (CajaFile *file,
45954597

45964598
if (gicon) {
45974599
icon = caja_icon_info_lookup (gicon, size, scale);
4598-
if (caja_icon_info_is_fallback (icon)) {
4599-
g_object_unref (icon);
4600-
icon = caja_icon_info_lookup (get_default_file_icon (flags), size, scale);
4601-
}
46024600
g_object_unref (gicon);
46034601
return icon;
46044602
} else {

libcaja-private/caja-icon-info.c

Lines changed: 67 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,7 @@ typedef struct
188188
GIcon *icon;
189189
int scale;
190190
int size;
191-
} LoadableIconKey;
192-
193-
typedef struct
194-
{
195-
char *filename;
196-
int scale;
197-
int size;
198-
} ThemedIconKey;
191+
} IconKey;
199192

200193
static GHashTable *loadable_icon_cache = NULL;
201194
static GHashTable *themed_icon_cache = NULL;
@@ -290,100 +283,64 @@ caja_icon_info_clear_caches (void)
290283
}
291284

292285
static guint
293-
loadable_icon_key_hash (LoadableIconKey *key)
286+
icon_key_hash (IconKey *key)
294287
{
295-
return g_icon_hash (key->icon) ^ key->scale ^ key->size;
288+
return g_icon_hash (key->icon) ^ key->size;
296289
}
297290

298291
static gboolean
299-
loadable_icon_key_equal (const LoadableIconKey *a,
300-
const LoadableIconKey *b)
292+
icon_key_equal (const IconKey *a,
293+
const IconKey *b)
301294
{
302295
return a->size == b->size &&
303296
a->scale == b->scale &&
304297
g_icon_equal (a->icon, b->icon);
305298
}
306299

307-
static LoadableIconKey *
308-
loadable_icon_key_new (GIcon *icon,
309-
int scale,
310-
int size)
300+
static IconKey *
301+
icon_key_new (GIcon *icon,
302+
int scale,
303+
int size)
311304
{
312-
LoadableIconKey *key;
305+
IconKey *key;
313306

314-
key = g_slice_new (LoadableIconKey);
307+
key = g_slice_new (IconKey);
315308
key->icon = g_object_ref (icon);
316-
key->scale = scale;
317309
key->size = size;
318310

319311
return key;
320312
}
321313

322314
static void
323-
loadable_icon_key_free (LoadableIconKey *key)
315+
icon_key_free (IconKey *key)
324316
{
325317
g_object_unref (key->icon);
326-
g_slice_free (LoadableIconKey, key);
327-
}
328-
329-
static guint
330-
themed_icon_key_hash (ThemedIconKey *key)
331-
{
332-
return g_str_hash (key->filename) ^ key->size;
333-
}
334-
335-
static gboolean
336-
themed_icon_key_equal (const ThemedIconKey *a,
337-
const ThemedIconKey *b)
338-
{
339-
return a->size == b->size &&
340-
a->scale == b->scale &&
341-
g_str_equal (a->filename, b->filename);
342-
}
343-
344-
static ThemedIconKey *
345-
themed_icon_key_new (const char *filename,
346-
int scale,
347-
int size)
348-
{
349-
ThemedIconKey *key;
350-
351-
key = g_slice_new (ThemedIconKey);
352-
key->filename = g_strdup (filename);
353-
key->scale = scale;
354-
key->size = size;
355-
356-
return key;
357-
}
358-
359-
static void
360-
themed_icon_key_free (ThemedIconKey *key)
361-
{
362-
g_free (key->filename);
363-
g_slice_free (ThemedIconKey, key);
318+
g_slice_free (IconKey, key);
364319
}
365320

366321
CajaIconInfo *
367322
caja_icon_info_lookup (GIcon *icon,
368323
int size,
369324
int scale)
370325
{
326+
GtkIconTheme *icon_theme;
327+
GtkIconInfo *gtkicon_info;
328+
371329
CajaIconInfo *icon_info;
372-
GdkPixbuf *pixbuf;
373330

374-
if (G_IS_LOADABLE_ICON (icon))
375-
{
376-
LoadableIconKey lookup_key;
377-
LoadableIconKey *key;
331+
icon_theme = gtk_icon_theme_get_default ();
332+
333+
if (G_IS_LOADABLE_ICON (icon)) {
334+
GdkPixbuf *pixbuf;
335+
IconKey lookup_key;
336+
IconKey *key;
378337
GInputStream *stream;
379338

380-
if (loadable_icon_cache == NULL)
381-
{
382-
loadable_icon_cache =
383-
g_hash_table_new_full ((GHashFunc)loadable_icon_key_hash,
384-
(GEqualFunc)loadable_icon_key_equal,
385-
(GDestroyNotify) loadable_icon_key_free,
386-
(GDestroyNotify) g_object_unref);
339+
if (loadable_icon_cache == NULL) {
340+
loadable_icon_cache = g_hash_table_new_full ((GHashFunc) icon_key_hash,
341+
(GEqualFunc) icon_key_equal,
342+
(GDestroyNotify) icon_key_free,
343+
(GDestroyNotify) g_object_unref);
387344
}
388345

389346
lookup_key.icon = icon;
@@ -410,96 +367,66 @@ caja_icon_info_lookup (GIcon *icon,
410367
g_object_unref (stream);
411368
}
412369

413-
icon_info = caja_icon_info_new_for_pixbuf (pixbuf, scale);
414-
415-
key = loadable_icon_key_new (icon, scale, size);
416-
g_hash_table_insert (loadable_icon_cache, key, icon_info);
417-
418-
return g_object_ref (icon_info);
419-
}
420-
else if (G_IS_THEMED_ICON (icon))
421-
{
422-
const char * const *names;
423-
ThemedIconKey lookup_key;
424-
ThemedIconKey *key;
425-
GtkIconTheme *icon_theme;
426-
GtkIconInfo *gtkicon_info;
427-
const char *filename;
428-
429-
if (themed_icon_cache == NULL)
430-
{
431-
themed_icon_cache =
432-
g_hash_table_new_full ((GHashFunc)themed_icon_key_hash,
433-
(GEqualFunc)themed_icon_key_equal,
434-
(GDestroyNotify) themed_icon_key_free,
435-
(GDestroyNotify) g_object_unref);
370+
if (!pixbuf) {
371+
gtkicon_info = gtk_icon_theme_lookup_icon_for_scale (icon_theme,
372+
"text-x-generic",
373+
size,
374+
scale,
375+
GTK_ICON_LOOKUP_FORCE_SIZE);
376+
pixbuf = gtk_icon_info_load_icon (gtkicon_info, NULL);
436377
}
437378

438-
names = g_themed_icon_get_names (G_THEMED_ICON (icon));
439379

440-
icon_theme = gtk_icon_theme_get_default ();
441-
gtkicon_info = gtk_icon_theme_choose_icon_for_scale (icon_theme, (const char **)names,
442-
size, scale, 0);
380+
icon_info = caja_icon_info_new_for_pixbuf (pixbuf, scale);
443381

444-
if (gtkicon_info == NULL)
445-
{
446-
return caja_icon_info_new_for_pixbuf (NULL, scale);
447-
}
382+
key = icon_key_new (icon, scale, size);
383+
g_hash_table_insert (loadable_icon_cache, key, icon_info);
384+
g_clear_object (&pixbuf);
448385

449-
filename = gtk_icon_info_get_filename (gtkicon_info);
450-
if (filename == NULL) {
451-
g_object_unref (gtkicon_info);
452-
return caja_icon_info_new_for_pixbuf (NULL, scale);
386+
return g_object_ref (icon_info);
387+
} else {
388+
IconKey lookup_key;
389+
IconKey *key;
390+
if (themed_icon_cache == NULL) {
391+
themed_icon_cache = g_hash_table_new_full ((GHashFunc) icon_key_hash,
392+
(GEqualFunc) icon_key_equal,
393+
(GDestroyNotify) icon_key_free,
394+
(GDestroyNotify) g_object_unref);
453395
}
454-
455-
lookup_key.filename = (char *)filename;
396+
lookup_key.icon = icon;
456397
lookup_key.scale = scale;
457398
lookup_key.size = size;
458399

459400
icon_info = g_hash_table_lookup (themed_icon_cache, &lookup_key);
460-
if (icon_info)
461-
{
462-
g_object_unref (gtkicon_info);
401+
if (icon_info) {
463402
return g_object_ref (icon_info);
464403
}
465404

466-
icon_info = caja_icon_info_new_for_icon_info (gtkicon_info, scale);
405+
gtkicon_info = NULL;
467406

468-
key = themed_icon_key_new (filename, scale, size);
469-
g_hash_table_insert (themed_icon_cache, key, icon_info);
407+
gtkicon_info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme,
408+
icon,
409+
size,
410+
scale,
411+
0);
470412

471-
g_object_unref (gtkicon_info);
472-
473-
return g_object_ref (icon_info);
474-
}
475-
else
476-
{
477-
GdkPixbuf *pixbuf;
478-
GtkIconInfo *gtk_icon_info;
479-
480-
gtk_icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (gtk_icon_theme_get_default (),
481-
icon,
482-
size,
483-
scale,
484-
GTK_ICON_LOOKUP_FORCE_SIZE);
485-
if (gtk_icon_info != NULL)
486-
{
487-
pixbuf = gtk_icon_info_load_icon (gtk_icon_info, NULL);
488-
g_object_unref (gtk_icon_info);
489-
}
490-
else
491-
{
492-
pixbuf = NULL;
413+
if (!gtkicon_info) {
414+
gtkicon_info = gtk_icon_theme_lookup_icon_for_scale (icon_theme,
415+
"text-x-generic",
416+
size,
417+
scale,
418+
0);
493419
}
494420

495-
icon_info = caja_icon_info_new_for_pixbuf (pixbuf, scale);
421+
icon_info = caja_icon_info_new_for_icon_info (gtkicon_info, scale);
422+
g_object_unref (gtkicon_info);
496423

497-
if (pixbuf != NULL) {
498-
g_object_unref (pixbuf);
499-
}
424+
key = icon_key_new (icon,scale, size);
425+
g_hash_table_insert (themed_icon_cache, key, icon_info);
500426

501-
return icon_info;
427+
return g_object_ref (icon_info);
502428
}
429+
503430
}
504431

505432
CajaIconInfo *

0 commit comments

Comments
 (0)