fast QListView numerical sort

U

Uwe Mayer

Hi,

Using PyQt I got a QListView with about 800 entries now (but its intended to
be scalable up to about 3000).
The first column contains numerical data. Now Qt does the sorting all by its
self and quite fast enough. By default it sorts alphanumerically, i.e. 1 10
100 101 110 111 2 ...

Solutions on the web suggested left padding the digits with white spaces
which didn't work for me.
Left padding with 0's does not look good.
Qt Manual says you can overwrite the compare method QListViewItem.compare -
which I did:

QListViewItem.compare = lambda s,a,b,c: s.text(0).toInt()[0]
-a.text(0).toInt()[0]

The compare method returns < 0 for "smaller", 0 for "equal", > 0 for
"bigger".
Doing so works, but causes a 2 sec delay each time a re-sort has to be done
- which is rather annoying (at only less than 1/3 of its expected load!)

Solutions I could come up with are:
a. derive a C++ QListViewItem that does the numerical sorting and use this
instead of the default QListViewItem in the hope it'll be faster
pro: probably the easyest (faster? fast enough?)
con: not portable

b. implement all sorting and inserting related functions by myself in Python
and do the sorting from Python
pro: portable
con: much more coding to be done; probably contains more bugs

Which do you favour or do you have other suggestions?

Thanks
Uwe
 
A

Andy Salnikov

Uwe Mayer said:
Hi,

Using PyQt I got a QListView with about 800 entries now (but its intended to
be scalable up to about 3000).
The first column contains numerical data. Now Qt does the sorting all by its
self and quite fast enough. By default it sorts alphanumerically, i.e. 1 10
100 101 110 111 2 ...

Solutions on the web suggested left padding the digits with white spaces
which didn't work for me.

Hmm, I'd expect it to work.
Left padding with 0's does not look good.
Qt Manual says you can overwrite the compare method QListViewItem.compare -
which I did:

QListViewItem.compare = lambda s,a,b,c: s.text(0).toInt()[0]
-a.text(0).toInt()[0]

The compare method returns < 0 for "smaller", 0 for "equal", > 0 for
"bigger".
Doing so works, but causes a 2 sec delay each time a re-sort has to be done
- which is rather annoying (at only less than 1/3 of its expected load!)
Well, this probably comes from PyQt's nature - its a layer between Qt
(which is C++)
and Python. QListView calls some C++ function to sort its items, which in
turn makes
a lot of calls to QListViewItem::compare(). Every call to compare() has to
be
translated from C++ world to Python world, and the result returned back.
Solutions I could come up with are:
a. derive a C++ QListViewItem that does the numerical sorting and use this
instead of the default QListViewItem in the hope it'll be faster
pro: probably the easyest (faster? fast enough?)
con: not portable
That should be fast enough, I guess, this is the ultimate speed you can
get.
Why isn't it portable?
b. implement all sorting and inserting related functions by myself in Python
and do the sorting from Python
pro: portable
con: much more coding to be done; probably contains more bugs
I'm not at all sure that it will be faster than what you currently have.
It sure might be
because you'd remove most of that translation layer calls.
Which do you favour or do you have other suggestions?
I'd say check that space-filled approach. It should work one way or
another.

Cheers,
Andy.
 
U

Uwe Mayer

Well, this probably comes from PyQt's nature - its a layer between Qt
(which is C++)
and Python. QListView calls some C++ function to sort its items, which in
turn makes
a lot of calls to QListViewItem::compare(). Every call to compare() has to
be
translated from C++ world to Python world, and the result returned back.

Yes. I found another suggestion on the web: overwriting the .key() method,
which has to return the value that is to be compared during sorting.
The .key() method returns a left zero-padded string and thus the string
sorting will yield the correct results.
However, this is even slower than overwriting the .compare() method.
That should be fast enough, I guess, this is the ultimate speed you can
get.
Why isn't it portable?

.... yeah, it surely will run on Windows, but then I'll have to take care of
the cross-compilation, etc. Which Windows user has a C++ compiler
installed?
Portability is surely my (personally) least problem, but working with Python
its not nice giving up this "portability" feature: take the sources to
another platform - run.

Another possibility: Have you got any experience with Psyco? I just heard
about it, but didn't go into much details until now. Perhaps the
just-in-time compiler will boost the performance...

Thanks
Uwe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top