GFileEnumerator takes much longer to list PNG files or files with unrecognized extensions
I noticed this when trying to open my thumbnails directory ~/.cache/thumbnails/normal
in ristretto, Xfce's image viewer, which uses GFileEnumerator. This took a long time, whereas I knew ristretto could open directories containing 10,000 to 20,000 images in a few seconds.
So I copied 10,000 thumbnails into a test directory and used this reproducer to run a few tests:
#define N_FILES 100
#define N_ITERS 10
GTimer *timer;
GMainLoop *loop;
gint iters;
static void
next_files_finish (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
GFileEnumerator *enumerator = G_FILE_ENUMERATOR (source_object);
GList *infos = g_file_enumerator_next_files_finish (enumerator, res, NULL);
g_printerr ("%.2f ms\n", g_timer_elapsed (timer, NULL) * 1000);
g_timer_reset (timer);
if (infos == NULL || ++iters >= N_ITERS)
{
g_object_unref (enumerator);
g_main_loop_quit (loop);
return;
}
g_list_free_full (infos, g_object_unref);
g_file_enumerator_next_files_async (enumerator, N_FILES, G_PRIORITY_DEFAULT, NULL, next_files_finish, NULL);
}
static void
enumerate_children_finish (GObject *dir,
GAsyncResult *res,
gpointer user_data)
{
GFileEnumerator *enumerator = g_file_enumerate_children_finish (G_FILE (dir), res, NULL);
if (enumerator == NULL)
{
g_main_loop_quit (loop);
return;
}
g_file_enumerator_next_files_async (enumerator, N_FILES, G_PRIORITY_DEFAULT, NULL, next_files_finish, NULL);
}
gint main (gint argc, gchar **argv)
{
GFile *file = g_file_new_for_path ("/home/user/td");
loop = g_main_loop_new (NULL, FALSE);
timer = g_timer_new ();
g_file_enumerate_children_async (file, "standard::name,standard::content-type",
G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, NULL,
enumerate_children_finish, NULL);
g_main_loop_run (loop);
g_main_loop_unref (loop);
g_object_unref (file);
g_timer_destroy (timer);
}
With the constants defined above, it lists 1,000 files in blocks of 100 and displays the time taken for each block. Here's what it does for me with the thumbnails left as they are, i.e. with the extension .png
:
$ echo 1 | sudo tee /proc/sys/vm/drop_caches && ~/p
895.36 ms
638.79 ms
744.88 ms
585.45 ms
566.91 ms
597.58 ms
561.13 ms
724.62 ms
629.97 ms
707.85 ms
And here's what it looks like renaming all thumbnails to .jpg
:
$ rename .png .jpg ~/td/*
$ echo 1 | sudo tee /proc/sys/vm/drop_caches && ~/p
322.37 ms
16.88 ms
13.37 ms
22.03 ms
17.92 ms
25.42 ms
34.72 ms
16.31 ms
10.55 ms
8.59 ms
So I tried a few other extensions without finding the same PNG times, except by setting an unknown extension, for example .xxx
:
$ rename .jpg .xxx ~/td/*
$ echo 1 | sudo tee /proc/sys/vm/drop_caches && ~/p
608.39 ms
715.27 ms
553.15 ms
602.00 ms
538.21 ms
481.52 ms
589.34 ms
509.56 ms
460.72 ms
784.75 ms
Perhaps it's normal for the processing time to vary a little depending on the file extension, but is it normal for it to vary so much?
GLib 2.80.0 on Arch Linux