Results 1 to 20 of 22

Thread: Sorting a QVector

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Sorting a QVector

    Yes, bubblesort is never used in serious applications. It is now mainly used for educational purposes.

    Edit:

    Another thing about your code (if you choose to keep it). You can shave off some lines of code by using struct assignment.

    Qt Code:
    1. Review temp;
    2. temp = vector.at(k);
    3. vector[k] = vector.at(k-1);
    4. vector[k-1] = temp;
    To copy to clipboard, switch view to plain text mode 

    And, well, you can also just use the standard C++ swap() or the Qt qSwap() function. (They're identical. One wonders why Qt has its own version.)

    Qt Code:
    1. qSwap(vector[k], vector[k-1]);
    To copy to clipboard, switch view to plain text mode 
    Last edited by Michiel; 10th August 2007 at 20:32.
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Sorting a QVector

    Quote Originally Posted by Michiel View Post
    And, well, you can also just use the standard C++ swap() or the Qt qSwap() function. (They're identical. One wonders why Qt has its own version.)
    They are not identical. qSwap() is better than most swap() implementations.

  3. #3
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Sorting a QVector

    Quote Originally Posted by wysota View Post
    They are not identical. qSwap() is better than most swap() implementations.
    Interesting. How (in)efficient can a swap function be? Does it swap at bit-level using xor or something?
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  4. #4
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Sorting a QVector

    Well, I don't know about its performance:
    Qt Code:
    1. template <typename T>
    2. inline void qSwap(T &value1, T &value2)
    3. {
    4. T t = value1;
    5. value1 = value2;
    6. value2 = t;
    7. }
    To copy to clipboard, switch view to plain text mode 
    I think it is compiler dependent. It is up to the compiler to optimize this code.
    Basically, there are 3 memcpy's, since that is what is going on.

    Maybe a good compiler will optimize that using mmx, sse or whatever instruction sets are available.

    Regards

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Sorting a QVector

    Quote Originally Posted by Michiel View Post
    Interesting. How (in)efficient can a swap function be? Does it swap at bit-level using xor or something?
    The trivial implementation of swap is something like:

    Qt Code:
    1. template< typename T> void swap(T& x, T& y){
    2. T tmp = x;
    3. x = y;
    4. y = tmp;
    5. }
    To copy to clipboard, switch view to plain text mode 

    Drawbacks:
    - three operations
    - uses assignment operator that can be quite complex (for example for trivial vector implementation)

    qSwap() tries to be smarter, for instance it can detect if operator=() needs to be used or if it can use memcpy() or similar, thus it is faster for movable types.

  6. #6
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Sorting a QVector

    Quote Originally Posted by wysota View Post
    The trivial implementation of swap is something like:
    I wasn't thinking of the trivial implementation. Because of exactly the drawbacks you describe.

    Quote Originally Posted by wysota View Post
    qSwap() tries to be smarter, for instance it can detect if operator=() needs to be used or if it can use memcpy() or similar, thus it is faster for movable types.
    operator=() should never be used for a swap operation. Why use deep copies if, after the function call, you still end up with exactly the same dynamic data? A shallow copy only moves the pointers around (and the primitive types). For the swap function this should be enough. And I'd be surprised if the standard C++ implementation did it differently.

    Of course, this is only true for reasonable implementations of operator=(). But one can't assume that operator=() is going to be used in swap(). All that is required after the swap is that X behaves as Y did and Y behaves as X did.
    Last edited by Michiel; 10th August 2007 at 23:28.
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  7. #7
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Sorting a QVector

    operator=() should never be used for a swap operation. Why use deep copies if, after the function call, you still end up with exactly the same dynamic data? A shallow copy only moves the pointers around (and the primitive types). For the swap function this should be enough. And I'd be surprised if the standard C++ implementation did it differently.
    But it will use the =() operator if the type T provides it(qSwap is a template function).
    Otherwise it is just a memcpy over the destination.

  8. #8
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Sorting a QVector

    Quote Originally Posted by marcel View Post
    But it will use the =() operator if the type T provides it(qSwap is a template function).
    Otherwise it is just a memcpy over the destination.
    Exactly. And it should just be a memcpy. When would you want a swap function to use operator=()?
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Sorting a QVector

    When you can't memcpy objects. And you can't memcpy most complex objects... As far as I understand the compiler will only "memcpy" PODs.

    http://doc.trolltech.com/latest/qtgl...CLARE_TYPEINFO
    http://doc.trolltech.com/qq/qq19-containers.html (take a look at the paragraph mentioning Q_DECLARE_TYPEINFO)

    And answering your question about wanting to use an assignment operator for swapping - for instance when you have a class that is to be used in multithreaded environment. Swaping using memcpy() and modifying the object from within another thread at the same time will break it completely. You have to use operator=() there to be certain you're blocking access with mutexes.
    Last edited by wysota; 11th August 2007 at 00:06. Reason: Added some content

  10. #10
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Sorting a QVector

    Quote Originally Posted by wysota View Post
    And answering your question about wanting to use an assignment operator for swapping - for instance when you have a class that is to be used in multithreaded environment. Swaping using memcpy() and modifying the object from within another thread at the same time will break it completely. You have to use operator=() there to be certain you're blocking access with mutexes.
    Hm. Yes, I suppose that's true. However, if that is the only reason, deep copies are still being made when they don't have to. You could have a list with 100.000 values that must be copied twice in the name of thread safety.

    If there is another way to isolate the swap operation, things could be much more efficient.
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  11. #11
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Sorting a QVector

    If there is another way to isolate the swap operation, things could be much more efficient.
    If you are sure it is doable you can always implement your own using memcpy.

    And answering your question about wanting to use an assignment operator for swapping - for instance when you have a class that is to be used in multithreaded environment. Swaping using memcpy() and modifying the object from within another thread at the same time will break it completely. You have to use operator=() there to be certain you're blocking access with mutexes.
    How is qSwap thread safe?
    You still have to put a lock on the mem locations you want to swap even with qSwap.
    I don't mean about Qt classes that are already thread-safe, but a user class.
    Would one trade performance over implementing locking in the operator=() and not in some other place?
    Last edited by marcel; 11th August 2007 at 00:35.

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Sorting a QVector

    Actually qSwap doesn't use memcpy directly (4.3 beta):
    Qt Code:
    1. template <typename T>
    2. inline void qSwap(T &value1, T &value2)
    3. {
    4. if (!QTypeInfo<T>::isComplex || QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
    5. T t = value1;
    6. value1 = value2;
    7. value2 = t;
    8. } else {
    9. const void * const t = reinterpret_cast<const void * const &>(value1);
    10. const_cast<const void *&>(reinterpret_cast<const void * const &>(value1)) =
    11. reinterpret_cast<const void * const &>(value2);
    12. const_cast<const void *&>(reinterpret_cast<const void * const &>(value2)) = t;
    13. }
    14. }
    To copy to clipboard, switch view to plain text mode 

    I admit I don't understand those spells with casting, but they look smart

    It's not that qSwap is thread safe, it's that you can use such classes with it. You have to care about locking your class on your own. It's a general assumption about using operator=(), not about swapping items.

    Anyway we're highly offtopic here It doesn't really matter if you use qSwap or swap for sorting QVector.

  13. #13
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Sorting a QVector

    Quote Originally Posted by wysota View Post
    Actually qSwap doesn't use memcpy directly (4.3 beta):
    Weird enough. It must have remained a beta .
    I can't really find this implementation anywhere in 4.3.0 ( not beta ).

    I even made small test and stepped in qSwap. The one I posted above is used for all types.

    EDIT:
    I think those casts only switch the base addresses of the variables without actually swapping any memory or calling =() operators.

    Regards
    Last edited by marcel; 11th August 2007 at 11:23.

  14. #14
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Sorting a QVector

    I can't imagine a reason right now.
    However, even structure assignment is implemented in the language as member by member assignment.

    So, in wysota's example above, no memcpy will occur(although it would work), but the two QString members will be assigned one by one, causing QString:perator=() to intervene.

    Regards

Similar Threads

  1. Model sorting vs. selection
    By VlJE in forum Qt Programming
    Replies: 2
    Last Post: 25th October 2006, 16:46
  2. QVector problem
    By kingslee in forum Qt Programming
    Replies: 5
    Last Post: 19th October 2006, 10:42
  3. Column Sorting
    By sumsin in forum Qt Programming
    Replies: 1
    Last Post: 16th June 2006, 07:48
  4. QT4: Sorting in QTreeWidget (subclass)
    By Michiel in forum Qt Programming
    Replies: 21
    Last Post: 29th March 2006, 18:08
  5. [QT4] QTreeView, QAbstractItemModel and sorting
    By KShots in forum Qt Programming
    Replies: 3
    Last Post: 24th March 2006, 20:16

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.