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 764139 - Opening a 100 kB file takes about 45 seconds
Opening a 100 kB file takes about 45 seconds
Status: RESOLVED FIXED
Product: eog
Classification: Core
Component: general
3.20.x
Other All
: Normal normal
: ---
Assigned To: EOG Maintainers
EOG Maintainers
Depends on:
Blocks:
 
 
Reported: 2016-03-24 12:58 UTC by Andreas Nilsson
Modified: 2016-04-12 07:19 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
log output (537.74 KB, text/x-log)
2016-03-29 16:15 UTC, Andreas Nilsson
  Details
EogImage: Remove unused constructor (1.30 KB, patch)
2016-04-07 08:23 UTC, Debarshi Ray
none Details | Review
Reduce the number of g_file_query_info calls at start-up (5.96 KB, patch)
2016-04-07 08:23 UTC, Debarshi Ray
none Details | Review

Description Andreas Nilsson 2016-03-24 12:58:02 UTC
I'm experiencing very slow file operations when trying to use owncloud via webdav in Nautilus.
Opening a 100kB file can take up to 45 seconds.
Opening a 500kB file takes about the same time, so it seems independent of file-size. I also tried with a file that was 1.9MB.
All of these were png-files.
Comment 1 Ondrej Holy 2016-03-24 13:36:27 UTC
Hey! Thanks for your report. Please try to use gvfs-* cmd tools directly to be sure it is not a Nautilus/image viewer issue... btw what image viewer is used?

You can try following for example:
gvfs-cat dav://SERVER/FILE > /dev/null

Is it also so slow?
Comment 2 Andreas Nilsson 2016-03-24 14:44:43 UTC
That seems to take only 3-4 seconds. So a lot faster indeed.
The image viewer is eog. Also tried with Shotwell and Firefox. About as slow.
Comment 3 Bastien Nocera 2016-03-24 14:49:02 UTC
(In reply to Andreas Nilsson from comment #2)
> That seems to take only 3-4 seconds. So a lot faster indeed.
> The image viewer is eog. Also tried with Shotwell and Firefox. About as slow.

If copy and opening the file is loads faster than loading it from the remote, it's likely that it's doing too many seeks, which is like switching your SSD for a hard drive using turntable technology.
Comment 4 Ondrej Holy 2016-03-29 09:14:15 UTC
Yes, slowdown may be significant for dav backend if seeking is used, but I don't see any seek requests with eog for png files on webdav...

Please try to run gvfs manually and obtain debug log:
1/ pkill gvfs -u $(id -u); GVFS_DEBUG=1 GVFS_HTTP_DEBUG=all $(find /usr/lib* -name gvfsd) &> ~/gvfsd.log 
2/ gvfs-mount dav://SERVER/
3/ eog dav://SERVER/FILE
4/ provide gvfsd.log
(try again using nautilus if you don't see the slowdown this way)
Comment 5 Andreas Nilsson 2016-03-29 16:15:28 UTC
Created attachment 324953 [details]
log output

Does this look correct?
Comment 6 Ondrej Holy 2016-03-30 09:04:08 UTC
Thanks for the log. I see in the log...

- enumeration job of a root dir
- 155 query_info jobs for all files in the root dir
- read jobs for /airplane.png file 0.8MB

So we can exclude the possibility that it is caused by the seek requests. The slowdown is caused by the initial 155 query_info requests from eog, however those requests are not necessary. It just reads display-name, but it can be simply obtained from the previous enumeration job...
Comment 7 Ondrej Holy 2016-03-30 09:06:52 UTC
It is caused by the patch from Bug 754731.

Eog should cache GFileInfo (or at least display-name) from the initial enumeration to avoid the slowdown.
Comment 8 Debarshi Ray 2016-03-30 09:51:00 UTC
(In reply to Ondrej Holy from comment #7)
> It is caused by the patch from Bug 754731.
> 
> Eog should cache GFileInfo (or at least display-name) from the initial
> enumeration to avoid the slowdown.

While I agree that eog could coalesce / cache some of those g_file_query_info calls, I am not sure that it was much faster before bug 754731.

If you look at these patches:

commit 68a5a0d842d993da6957dee74535ee15c8742394
Author: Felix Riemann <friemann@gnome.org>
Date:   Fri Sep 11 21:00:19 2015 +0200

    EogPropertiesDialog: Use standard::display-name when showing the parent
    
    This simply adapts the changes from commit fff55c6a to the
    properties dialog, which shares some code with the EogMetadataSidebar.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=754731

commit fff55c6afdd1c159c1ec554316fa6170f561cbe1
Author: Debarshi Ray <debarshir@gnome.org>
Date:   Tue Sep 8 18:18:00 2015 +0200

    EogMetadataSidebar: Use standard::display-name when showing the parent
    
    https://bugzilla.gnome.org/show_bug.cgi?id=754731


... then you will notice that pd_update_general_tab and eog_metadata_sidebar_update_general_section already had synchronous g_file_query_info calls in the main/UI thread. You will find similar calls in a few other places too.

That's why I added a separate asynchronous g_file_query_info_async call in the above patches to avoid making it any worse.

Let me investigate a bit more.
Comment 9 Debarshi Ray 2016-03-30 11:05:06 UTC
I reverted the patches from bug 754731 locally, and ran it as:
$ /opt/bin/eog davs://rishi@cloud.gnome.org/remote.php/webdav/path/to/foo.jpg

I found that the number of GVfsJobQueryInfo decreased by only 2. ie. the 2 g_file_query_info_async calls to get the standard::display-name of foo.jpg's parent folder for the sidebar and properties dialog.

Setting a break point on g_file_query_info revealed something more interesting:

(gdb) break g_file_query_info
Function "g_file_query_info" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (g_file_query_info) pending.
(gdb) run davs://rishi@cloud.gnome.org/remote.php/webdav/path/to/foo.jpg

...

Breakpoint 1, g_file_query_info (file=0x790f30, attributes=0x7ffff7bbdaf8 "standard::type,standard::content-type", 
    flags=G_FILE_QUERY_INFO_NONE, cancellable=0x0, error=0x0) at gfile.c:1193
1193	{
(gdb) bt
  • #0 g_file_query_info
    at gfile.c line 1193
  • #1 eog_job_model_run
    at eog-jobs.c line 678
  • #2 eog_job_model_run
    at eog-jobs.c line 733
  • #3 eog_job_scheduler
    at eog-job-scheduler.c line 153
  • #4 eog_job_scheduler
    at eog-job-scheduler.c line 128
  • #5 g_thread_proxy
    at gthread.c line 778
  • #6 start_thread
  • #7 clone
  • #0 g_file_query_info
    at gfile.c line 1193
  • #1 eog_list_store_add_files
    at eog-list-store.c line 561
  • #2 eog_job_model_run
    at eog-jobs.c line 742
  • #3 eog_job_scheduler
    at eog-job-scheduler.c line 153
  • #4 eog_job_scheduler
    at eog-job-scheduler.c line 128
  • #5 g_thread_proxy
    at gthread.c line 778
  • #6 start_thread
  • #7 clone
  • #0 g_file_query_info
    at gfile.c line 1193
  • #1 eog_list_store_add_files
    at eog-list-store.c line 591
  • #2 eog_job_model_run
    at eog-jobs.c line 742
  • #3 eog_job_scheduler
    at eog-job-scheduler.c line 153
  • #4 eog_job_scheduler
    at eog-job-scheduler.c line 128
  • #5 g_thread_proxy
    at gthread.c line 778
  • #6 start_thread
  • #7 clone
  • #0 g_file_query_info
    at gfile.c line 1193
  • #1 eog_image_get_caption
    at eog-image.c line 2016
  • #2 eog_image_get_collate_key
    at eog-image.c line 2055
  • #3 eog_list_store_compare_func
    at eog-list-store.c line 114
  • #4 gtk_list_store_compare_func
  • #5 node_find_closest
    at gsequence.c line 1753
  • #6 node_insert_sorted
    at gsequence.c line 1991
  • #7 g_sequence_sort_iter
    at gsequence.c line 890
  • #8 gtk_list_store_sort
  • #9 eog_list_store_add_files
    at eog-list-store.c line 620
  • #10 eog_job_model_run
    at eog-jobs.c line 742
  • #11 eog_job_scheduler
    at eog-job-scheduler.c line 153
  • #12 eog_job_scheduler
    at eog-job-scheduler.c line 128
  • #13 g_thread_proxy
    at gthread.c line 778
  • #14 start_thread
  • #15 clone
  • #0 g_file_query_info
    at gfile.c line 1193
  • #1 eog_image_get_caption
    at eog-image.c line 2016
  • #2 eog_image_get_collate_key
    at eog-image.c line 2055
  • #3 eog_list_store_compare_func
    at eog-list-store.c line 114
  • #4 gtk_list_store_compare_func
  • #5 node_find_closest
    at gsequence.c line 1753
  • #6 node_insert_sorted
    at gsequence.c line 1991
  • #7 g_sequence_sort_iter
    at gsequence.c line 890
  • #8 gtk_list_store_sort
  • #9 eog_list_store_add_files
    at eog-list-store.c line 620
  • #10 eog_job_model_run
    at eog-jobs.c line 742
  • #11 eog_job_scheduler
    at eog-job-scheduler.c line 153
  • #12 eog_job_scheduler
    at eog-job-scheduler.c line 128
  • #13 g_thread_proxy
    at gthread.c line 778
  • #14 start_thread
  • #15 clone
  • #0 g_file_query_info
    at gfile.c line 1193
  • #1 eog_image_get_caption
    at eog-image.c line 2016
  • #2 eog_image_get_collate_key
    at eog-image.c line 2055
  • #3 eog_list_store_compare_func
    at eog-list-store.c line 114
  • #4 gtk_list_store_compare_func
  • #5 node_find_closest
    at gsequence.c line 1753
  • #6 node_insert_sorted
    at gsequence.c line 1991
  • #7 g_sequence_sort_iter
    at gsequence.c line 890
  • #8 gtk_list_store_sort
  • #9 eog_list_store_add_files
    at eog-list-store.c line 620
  • #10 eog_job_model_run
    at eog-jobs.c line 742
  • #11 eog_job_scheduler
    at eog-job-scheduler.c line 153
  • #12 eog_job_scheduler
    at eog-job-scheduler.c line 128
  • #13 g_thread_proxy
    at gthread.c line 778
  • #14 start_thread
  • #15 clone
  • #0 g_file_query_info
    at gfile.c line 1193
  • #1 eog_image_get_caption
    at eog-image.c line 2016
  • #2 eog_image_get_collate_key
    at eog-image.c line 2055
  • #3 eog_list_store_compare_func
    at eog-list-store.c line 114
  • #4 gtk_list_store_compare_func
  • #5 node_find_closest
    at gsequence.c line 1753
  • #6 node_insert_sorted
    at gsequence.c line 1991
  • #7 g_sequence_sort_iter
    at gsequence.c line 890
  • #8 gtk_list_store_sort
  • #9 eog_list_store_add_files
    at eog-list-store.c line 620
  • #10 eog_job_model_run
    at eog-jobs.c line 742
  • #11 eog_job_scheduler
    at eog-job-scheduler.c line 153
  • #12 eog_job_scheduler
    at eog-job-scheduler.c line 128
  • #13 g_thread_proxy
    at gthread.c line 778
  • #14 start_thread
  • #15 clone

Comment 10 Debarshi Ray 2016-03-30 11:21:46 UTC
This means that we need to cut down on the g_file_query_info calls coming from eog_image_get_caption, when it gets called from eog_list_store_compare_func.

One option would be to pass a suitable GFileInfo object or the caption itself to EogImage during construction. As far as I can tell, the eog_image_new is unused, and eog_image_new_file is only called from eog_list_store_append_image_from_file. All the call sites of eog_list_store_append_image_from_file already have a GFileInfo around, so it looks feasible.

Does this make sense?
Comment 11 Ondrej Holy 2016-03-30 11:24:32 UTC
Rishi, sorry that I blamed your patch initially (I messed up grep somehow). So it seems that the culprit is query_info call in eog_image_get_caption...
Comment 12 Ondrej Holy 2016-03-30 11:28:30 UTC
(In reply to Debarshi Ray from comment #10)
> This means that we need to cut down on the g_file_query_info calls coming
> from eog_image_get_caption, when it gets called from
> eog_list_store_compare_func.
> 
> One option would be to pass a suitable GFileInfo object or the caption
> itself to EogImage during construction. As far as I can tell, the
> eog_image_new is unused, and eog_image_new_file is only called from
> eog_list_store_append_image_from_file. All the call sites of
> eog_list_store_append_image_from_file already have a GFileInfo around, so it
> looks feasible.
> 
> Does this make sense?

That's exactly what I had in mind when I was writting comment 7.
Comment 13 Debarshi Ray 2016-03-30 11:29:41 UTC
(In reply to Ondrej Holy from comment #11)
> Rishi, sorry that I blamed your patch

No need to apologize. :)
Comment 14 Andreas Nilsson 2016-03-30 12:40:59 UTC
Does most things point in the direction of EOG, or should I try and see what output I get from other image viewers?
Comment 15 Felix Riemann 2016-03-30 13:54:55 UTC
Well, eog_image_get_caption should only be slow the first time as the result is cached for each image.

What you're probably seeing here is one of the deficiencies of eog's folder browsing capability. The thing is that eog is enumerating the whole folder before showing the actual image. That is causing the get_caption calls for all images in that folder, together with the added network/DAV latency, this is likely going to be very slow. I think #495825 is the ticket first describing this for huge local folders.

To verify: If you copy the image to a separate folder (where it's alone) it should open much faster.
Comment 16 Debarshi Ray 2016-03-30 14:16:03 UTC
(In reply to Andreas Nilsson from comment #14)
> Does most things point in the direction of EOG, or should I try and see what
> output I get from other image viewers?

Yes, this is a bug in Eye of GNOME.
Comment 17 Debarshi Ray 2016-03-30 14:28:03 UTC
(In reply to Felix Riemann from comment #15)
> Well, eog_image_get_caption should only be slow the first time as the result
> is cached for each image.

Yes, it is true that the caption (ie. the standard::display-name of the file) is cached once it has been read. However, I think we can do better. I think (see comment 10) we can already have the caption before constructing an EogImage instance. That means that we avoid one g_file_query_info call that can potentially hit the network and can be much more slower than a corresponding call for a local file.

This extra g_file_query_info call to get the caption is a problem because it gets called from the GtkTreeIterCompareFunc. This means that it gets called for each file in the folder.

> What you're probably seeing here is one of the deficiencies of eog's folder
> browsing capability. The thing is that eog is enumerating the whole folder
> before showing the actual image. That is causing the get_caption calls for
> all images in that folder, together with the added network/DAV latency, this
> is likely going to be very slow. I think #495825 is the ticket first
> describing this for huge local folders.

Yes, it would be nicer to first render the file that was passed to eog (ie. bug 495825) before iterating over the folder. Even then, we can avoid this extra g_file_query_info because we can combine it with the g_file_enumerate_children or the other g_file_query_info calls that we already have.

Let me try to write some patches to illustrate what I mean.
Comment 18 Debarshi Ray 2016-04-07 08:23:31 UTC
Created attachment 325522 [details] [review]
EogImage: Remove unused constructor
Comment 19 Debarshi Ray 2016-04-07 08:23:59 UTC
Created attachment 325523 [details] [review]
Reduce the number of g_file_query_info calls at start-up
Comment 20 Debarshi Ray 2016-04-07 08:52:21 UTC
I haven't had time to thoroughly test these patches, but they should illustrate what I meant earlier. On master with gtk-3-20, I am getting a crash while drawing, which doesn't seem to happen with gnome-3-18 and gtk-3-18. I need to check what's up with that.
Comment 21 Debarshi Ray 2016-04-07 17:46:58 UTC
I think the crashes are due to this commit:

commit 88c4f54eb9cee69b1eebef462df27f76119bec62
Author: Felix Riemann <friemann@gnome.org>
Date:   Mon Feb 15 20:49:48 2016 +0100

    EogScrollView: Implement simple two-pass filtering
    
    Show the filtered image only after a short time.
    This should improve the UI's responsiveness quite a bit.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=665897

Let's pursue it elsewhere.

As far as this bug is concerned, in a directory with 12 files, these patches reduce the number of GVfsJobQueryInfo seen by GVfs' WebDAV backend to from 22 to 10.
Comment 22 Felix Riemann 2016-04-11 17:39:37 UTC
(In reply to Debarshi Ray from comment #21)
> As far as this bug is concerned, in a directory with 12 files, these patches
> reduce the number of GVfsJobQueryInfo seen by GVfs' WebDAV backend to from
> 22 to 10.

Really? Shouldn't that be 12?
Comment 23 Debarshi Ray 2016-04-11 18:02:44 UTC
(In reply to Felix Riemann from comment #22)
> (In reply to Debarshi Ray from comment #21)
> > As far as this bug is concerned, in a directory with 12 files, these patches
> > reduce the number of GVfsJobQueryInfo seen by GVfs' WebDAV backend to from
> > 22 to 10.
> 
> Really? Shouldn't that be 12?

I don't think the 10 g_file_query_info calls are due to enumerating the directory. They are due to various other random things in the code. (Maybe some of them can be combined? I haven't checked.)

Plus, GVfs sees enumeration as a different job, so it won't be counted as a series of GVfsJobQueryInfos.

I think it is worth testing with a directory with a larger (>> 12) number of image files.
Comment 24 Felix Riemann 2016-04-11 19:15:17 UTC
(In reply to Debarshi Ray from comment #23)
> (In reply to Felix Riemann from comment #22)
> > (In reply to Debarshi Ray from comment #21)
> > > As far as this bug is concerned, in a directory with 12 files, these patches
> > > reduce the number of GVfsJobQueryInfo seen by GVfs' WebDAV backend to from
> > > 22 to 10.
> > 
> > Really? Shouldn't that be 12?
> 
> I don't think the 10 g_file_query_info calls are due to enumerating the
> directory. They are due to various other random things in the code. (Maybe
> some of them can be combined? I haven't checked.)
> 
> Plus, GVfs sees enumeration as a different job, so it won't be counted as a
> series of GVfsJobQueryInfos.

Okay, I didn't know that. That could very well be the explanation here. If you take out the enumeration it'll mostly leave you with the thumbnailing jobs whose number basically depends on the number of visible thumbnails in the collection bar.

> I think it is worth testing with a directory with a larger (>> 12) number of
> image files.

I tried on a folder of 129 images on a mounted DAVS share and used eog's builtin debugging functions to check when the last thumbnail jobs finishes. The difference is quite noticable. The unpatched eog uses 2.7 to 2.9 seconds, while the patched one needs just ~1.1s. It get's even faster (~0.7s vs. 2.8s) if you hide the collection pane and thus skip thumbnailing for the other images.
Comment 25 Felix Riemann 2016-04-11 19:50:09 UTC
Okay, I think this is manageable for 3.20.1.
Thanks again for the patches. :)

commit 65e61ccc81987643d9642a3b2bd49dd01674b591
Author: Debarshi Ray <>
Date:   Thu Apr 7 10:14:19 2016 +0200

    Reduce the number of g_file_query_info calls at start-up
    
    https://bugzilla.gnome.org/show_bug.cgi?id=764139

commit 14401d33e74946f0833e040434713da12745ef58
Author: Debarshi Ray <>
Date:   Thu Apr 7 09:27:06 2016 +0200

    EogImage: Remove unused constructor
    
    https://bugzilla.gnome.org/show_bug.cgi?id=764139
---
This problem has been fixed in our software repository. The fix will go into the next software release. Once that release is available, you may want to check for a software upgrade provided by your Linux distribution.
Comment 26 Debarshi Ray 2016-04-12 07:19:30 UTC
(In reply to Felix Riemann from comment #24)
> (In reply to Debarshi Ray from comment #23)
>> I think it is worth testing with a directory with a larger (>> 12) number of
>> image files.
> 
> I tried on a folder of 129 images on a mounted DAVS share and used eog's
> builtin debugging functions to check when the last thumbnail jobs finishes.
> The difference is quite noticable. The unpatched eog uses 2.7 to 2.9
> seconds, while the patched one needs just ~1.1s. It get's even faster (~0.7s
> vs. 2.8s) if you hide the collection pane and thus skip thumbnailing for the
> other images.

I see. Thanks for testing!