Wireshark mailing list archives

Re: Qt Interface Profiling


From: Evan Huus <eapache () gmail com>
Date: Fri, 26 Jun 2015 23:43:53 -0400

On Fri, Jun 26, 2015 at 7:03 PM, Guy Harris <guy () alum mit edu> wrote:

On Jun 26, 2015, at 2:45 PM, Evan Huus <eapache () gmail com> wrote:

I just ran the Qt interface through callgrind while loading a fairly
large capture. Stripping out all the dissector-related expenses, the
following two UI functions show up as hot spots:

qt_blurImage()
This is a Qt internal function for blurring, presumably from the fancy
start-up screen, but showed up as *surprisingly* expensive given the
fact that the startup screen was only a tiny fraction of the time
profiled. Is it possible it's still getting run with a blur factor of
0 on every screen or something?

It sounds, from the documentation, as if callgrind calculates a call graph; does it show who's calling qt_blurImage - 
from a quick look at the Qt 5.3.2 source, it's called from a couple of pixmap routines - and who's calling those 
routines?

I'll dig into this a bit more, it might just be that my profiling host
doesn't implement any OpenGL, so it's doing software raster which is
expensive

PacketListModel::recordLessThan()
This is ours, used for sorting the packet list. Not immediately sure
how to make it better, the GTK version is entirely different.

What columns do you have in your display?

100% default, so sorted by ID.

The custom column sort will look up the column's field over and over again, but if you're not using a custom column, 
that won't be an issue.

For columns that don't come from frame data, it does a string compare, or converts the string column data to a 
number, which probably does more work than it needs to if the underlying column isn't just a text string.

On the other hand, if you're just *loading* the capture, there shouldn't *be* any sorting - the frames should just be 
displayed in the order in which they're read!

According to

        http://doc.qt.io/qt-4.8/model-view-programming.html

(I'm using 4.8 documentation to avoid making Wireshark 5.x-only, so that it doesn't require the latest shiniest 
version of $DISTRIBUTION):

        There are two ways of approaching sorting in the model/view architecture; which approach to choose depends on 
your underlying model.

        If your model is sortable, i.e, if it reimplements the QAbstractItemModel::sort() function, both QTableView 
and QTreeView provide an API that allows you to sort your model data programmatically. In addition, you can enable 
interactive sorting (i.e. allowing the users to sort the data by clicking the view's headers), by connecting the 
QHeaderView::sortIndicatorChanged() signal to the QTableView::sortByColumn() slot or the QTreeView::sortByColumn() 
slot, respectively.

I believe we are currently using this approach. Our PacketListModel
implements sort(), which just dispatches to qSort() using
recordLessThan() as the comparator.

        The alternative approach, if your model do not have the required interface or if you want to use a list view 
to present your data, is to use a proxy model to transform the structure of your model before presenting the data in 
the view. This is covered in detail in the section on Proxy Models.

That section says:

        In the model/view framework, items of data supplied by a single model can be shared by any number of views, 
and each of these can possibly represent the same information in completely different ways. Custom views and 
delegates are effective ways to provide radically different representations of the same data. However, applications 
often need to provide conventional views onto processed versions of the same data, such as differently-sorted views 
onto a list of items.

        Although it seems appropriate to perform sorting and filtering operations as internal functions of views, 
this approach does not allow multiple views to share the results of such potentially costly operations. The 
alternative approach, involving sorting within the model itself, leads to the similar problem where each view has to 
display items of data that are organized according to the most recent processing operation.

        To solve this problem, the model/view framework uses proxy models to manage the information supplied between 
individual models and views. Proxy models are components that behave like ordinary models from the perspective of a 
view, and access data from source models on behalf of that view. The signals and slots used by the model/view 
framework ensure that each view is updated appropriately no matter how many proxy models are placed between itself 
and the source model.

So, as I understand it, we could:

        have an underlying model that is as thin a wrapper as possible around the frame_data_sequence;

        have a proxy model that has a trivial map when sorting by frame number (either mapping row N to frame N or 
mapping row N to frame (max + 1 - N), depending on whether we're sorting in increasing or decreasing order) and 
maintains its own map for other column types;

        perhaps have the sort method for that model make one pass over all the packets, constructing a map from 
frames to rows - given that you could be sorting a very large capture, and that if we generate the column data 
dynamically that means reading and dissecting each frame, a sort that accesses each frame only once and does so in 
sequential order, entering them into a sorted tree, might be faster than other sorts.

Yes, this sounds reasonable (and sounds like what we do in the GTK
version I think). In the sort() implementation Gerald left the
following comment:

// The Qt MVC documentation suggests using QSortFilterProxyModel for sorting
// and filtering. That seems like overkill but it might be something we want
// to do in the future.

Which I believe lines up with your hypothesis above.
___________________________________________________________________________
Sent via:    Wireshark-dev mailing list <wireshark-dev () wireshark org>
Archives:    https://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
             mailto:wireshark-dev-request () wireshark org?subject=unsubscribe


Current thread: