Bug 342266

Summary: Save file dialog may load very slowly if initial directory is large
Product: [Applications] kdialog Reporter: Anssi Hannula <anssi.hannula>
Component: generalAssignee: Brad Hards <bradh>
Status: RESOLVED DUPLICATE    
Severity: normal CC: nb64367
Priority: NOR    
Version: 1.0   
Target Milestone: ---   
Platform: Mageia RPMs   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Anssi Hannula 2014-12-28 03:34:02 UTC
Sometimes "kdialog --getsaveurl" loads up very slowly (i.e. takes minutes until it accepts any input, though it looks otherwise ready for the user).

It looks like this only happens when the initial starting directory has lots of files (e.g. 2000+).

Additionally, it looks like the loading time does not grow linearly - with 1000 files it took less than 5 seconds to load, but with 2000 files it takes 20-100sec to load.

This does not trigger always - usually the dialog is opened instantly. This also never happens when navigating to a large directory, just when the starting directory is one.

Backtrace captured from random moment is below. OProfile reveals that most of the CPU time is spent in font related functions. I'm guessing that somehow for every new file added, an auto-column-width action is triggered, which queries the font layout engine for the width of text for every file already listed, which would also explain the non-linear time.


(gdb) bt
#0  0x00007f5231dbf1d4 in malloc_consolidate (av=av@entry=0x7f52320f1cc0 <main_arena>) at malloc.c:4145
#1  0x00007f5231dc16b8 in _int_malloc (av=av@entry=0x7f52320f1cc0 <main_arena>, bytes=bytes@entry=2704) at malloc.c:3414
#2  0x00007f5231dc3da7 in __GI___libc_malloc (bytes=2704) at malloc.c:2892
#3  0x00007f5231dc44d8 in __GI___libc_realloc (oldmem=0x0, bytes=2704) at malloc.c:2973
#4  0x00007f5232813283 in QTextEngine::LayoutData::reallocate(int) (this=0x1cf1fb0, totalGlyphs=96) at text/qtextengine.cpp:2280
#5  0x00007f5232818bc0 in QTextEngine::attributes() const (this=0x2813e50, nGlyphs=<optimized out>) at text/qtextengine_p.h:535
#6  0x00007f5232818bc0 in QTextEngine::attributes() const (this=0x2813e50) at text/qtextengine.cpp:1411
#7  0x00007f5232826e3f in QTextLine::layout_helper(int) (this=this@entry=0x7fff9c5ce830, maxGlyphs=maxGlyphs@entry=2147483647) at text/qtextlayout.cpp:1746
#8  0x00007f523282876b in QTextLine::setLineWidth(double) (this=this@entry=0x7fff9c5ce830, width=<optimized out>) at text/qtextlayout.cpp:1534
#9  0x00007f5234a0f5ec in KFileItemDelegate::Private::layoutText(QTextLayout&, QString const&, int) const (this=this@entry=0x1cc1c90, layout=..., text="__redacted_directory_name__", maxWidth=maxWidth@entry=32757) at /usr/src/debug/kdelibs-4.14.3/kio/kio/kfileitemdelegate.cpp:375
#10 0x00007f5234a11032 in KFileItemDelegate::Private::displaySizeHint(QStyleOptionViewItemV4 const&, QModelIndex const&) const (this=0x1cc1c90, option=..., index=...)
    at /usr/src/debug/kdelibs-4.14.3/kio/kio/kfileitemdelegate.cpp:481
#11 0x00007f5234a12918 in KFileItemDelegate::sizeHint(QStyleOptionViewItem const&, QModelIndex const&) const (this=0x1947070, option=..., index=...)
    at /usr/src/debug/kdelibs-4.14.3/kio/kio/kfileitemdelegate.cpp:952
#12 0x00007f5232b020ae in QTreeView::sizeHintForColumn(int) const (this=<optimized out>, column=0) at itemviews/qtreeview.cpp:2748
#13 0x00007f5232ad4058 in QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode, bool) (this=
    0x1c76650, globalMode=globalMode@entry=QHeaderView::ResizeToContents, useGlobalMode=useGlobalMode@entry=true) at itemviews/qheaderview.cpp:3028
#14 0x00007f5232ad443e in QHeaderView::resizeSections(QHeaderView::ResizeMode) (this=this@entry=0x1c762d0, mode=mode@entry=QHeaderView::ResizeToContents) at itemviews/qheaderview.cpp:929
#15 0x00007f5234ddde42 in KDirOperatorDetailView::slotLayoutChanged() (this=0x1dfe230) at /usr/src/debug/kdelibs-4.14.3/kfile/kdiroperatordetailview.cpp:168
#16 0x00007f523346288a in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x18a5090, m=m@entry=0x7f52337b2860 <QAbstractItemModel::staticMetaObject>, local_signal_index=local_signal_index@entry=2, argv=argv@entry=0x0) at kernel/qobject.cpp:3567
#17 0x00007f52334abff3 in QAbstractItemModel::layoutChanged() (this=this@entry=0x18a5090) at .moc/release-shared/moc_qabstractitemmodel.cpp:176
#18 0x00007f5232b4831d in QSortFilterProxyModelPrivate::_q_sourceDataChanged(QModelIndex const&, QModelIndex const&) (this=0x1bedbd0, source_top_left=..., source_bottom_right=...)
    at itemviews/qsortfilterproxymodel.cpp:1184
#19 0x00007f523346288a in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x1b33190, m=m@entry=0x7f52337b2860 <QAbstractItemModel::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7fff9c5cf000) at kernel/qobject.cpp:3567
#20 0x00007f52334abf77 in QAbstractItemModel::dataChanged(QModelIndex const&, QModelIndex const&) (this=this@entry=0x1b33190, _t1=..., _t2=...) at .moc/release-shared/moc_qabstractitemmodel.cpp:163
#21 0x00007f52349f3783 in KDirModel::itemChanged(QModelIndex const&) (this=0x1b33190, index=...) at /usr/src/debug/kdelibs-4.14.3/kio/kio/kdirmodel.cpp:641
#22 0x00007f5234e02b45 in KFilePreviewGenerator::Private::dispatchIconUpdateQueue() (this=0x7f52320f1cc0 <main_arena>, this@entry=0x1ce3f70)
    at /usr/src/debug/kdelibs-4.14.3/kfile/kfilepreviewgenerator.cpp:760
#23 0x00007f5234e02cb1 in KFilePreviewGenerator::Private::resolveMimeType() (this=0x1ce3f70) at /usr/src/debug/kdelibs-4.14.3/kfile/kfilepreviewgenerator.cpp:872
#24 0x00007f5233466d61 in QObject::event(QEvent*) (this=0x18ca9a0, e=<optimized out>) at kernel/qobject.cpp:1222
#25 0x00007f52325c98cc in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=this@entry=0x1841180, receiver=receiver@entry=0x18ca9a0, e=e@entry=0x2812d10) at kernel/qapplication.cpp:4565
#26 0x00007f52325cff70 in QApplication::notify(QObject*, QEvent*) (this=this@entry=0x7fff9c5cf9d0, receiver=receiver@entry=0x18ca9a0, e=e@entry=0x2812d10) at kernel/qapplication.cpp:4351
#27 0x00007f5233ed41ba in KApplication::notify(QObject*, QEvent*) (this=0x7fff9c5cf9d0, receiver=0x18ca9a0, event=0x2812d10) at /usr/src/debug/kdelibs-4.14.3/kdeui/kernel/kapplication.cpp:311
#28 0x00007f523344ecad in QCoreApplication::notifyInternal(QObject*, QEvent*) (this=0x7fff9c5cf9d0, receiver=receiver@entry=0x18ca9a0, event=event@entry=0x2812d10) at kernel/qcoreapplication.cpp:953
#29 0x00007f5233451be1 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (event=0x2812d10, receiver=0x18ca9a0) at kernel/qcoreapplication.h:231
#30 0x00007f5233451be1 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (receiver=receiver@entry=0x0, event_type=event_type@entry=0, data=0x1808dd0)
    at kernel/qcoreapplication.cpp:1577
#31 0x00007f5233452073 in QCoreApplication::sendPostedEvents(QObject*, int) (receiver=receiver@entry=0x0, event_type=event_type@entry=0) at kernel/qcoreapplication.cpp:1470
#32 0x00007f523347bc63 in postEventSourceDispatch(GSource*, GSourceFunc, gpointer) () at kernel/qcoreapplication.h:236
#33 0x00007f523347bc63 in postEventSourceDispatch(GSource*, GSourceFunc, gpointer) (s=0x1833330) at kernel/qeventdispatcher_glib.cpp:280
#34 0x00007f522e2dcc6d in g_main_context_dispatch (context=0x1841520) at gmain.c:3111
#35 0x00007f522e2dcc6d in g_main_context_dispatch (context=context@entry=0x1841520) at gmain.c:3710
#36 0x00007f522e2dcf18 in g_main_context_iterate (context=context@entry=0x1841520, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3781
#37 0x00007f522e2dcfbc in g_main_context_iteration (context=0x1841520, may_block=1) at gmain.c:3842
#38 0x00007f523347bdad in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x180a750, flags=...) at kernel/qeventdispatcher_glib.cpp:425
#39 0x00007f5232667616 in QGuiEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=<optimized out>, flags=...) at kernel/qguieventdispatcher_glib.cpp:204
#40 0x00007f523344d931 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7fff9c5cf6f0, flags=...) at kernel/qeventloop.cpp:149
#41 0x00007f523344dc45 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7fff9c5cf6f0, flags=...) at kernel/qeventloop.cpp:204
#42 0x00007f5232a731bc in QDialog::exec() (this=0x7fff9c5cfa10) at dialogs/qdialog.cpp:562
#43 0x000000000040c956 in main ()


Reproducible: Sometimes

Steps to Reproduce:
1. mkdir TEST1231
2. for i in {1..2000}; do touch TEST1231/$i.txt; done
3. kdialog --getsaveurl $PWD/TEST1231

When this is reproducible, it seems to occur repeatedly - OTOH, when this decides to not reproduce immediately, repeatedly running it will not reproduce the issue.


Actual Results:  
Sometimes the dialog takes very long time load (20+ sec, probably a lot longer but I don't have an exact figure since this reproduces randomly).

Expected Results:  
Opened in less than 5 seconds, like when navigating to a large directory (instead of it being the initial directory).
Comment 1 Anssi Hannula 2014-12-28 03:34:52 UTC
This is with kdelibs version 4.14.3.
Comment 2 bunu 2014-12-28 11:09:42 UTC
[I am a GCI student]

I can't reproduce this on Ubuntu. I believe this problem can't be completely random. Could you tell something about your add ons and your custom settings. Did you have other applications running or was it worse at the beginning or the end of a session. Also I believe this is kio bug.
Comment 3 Myriam Schweingruber 2014-12-29 14:12:32 UTC
Could also be a Qt issue, see QTextEngine::LayoutData::reallocate(int)
Comment 4 Christoph Feck 2015-01-15 00:02:25 UTC

*** This bug has been marked as a duplicate of bug 293888 ***