Results 1 to 9 of 9

Thread: Question about iterator's choice

  1. #1
    Join Date
    Jan 2006
    Posts
    105
    Thanks
    38
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Question Question about iterator's choice

    Hi all, I have the following method where I manage various lists: "llistaAccions" is a list containing identificators to the actions that I need to execute sequentally until the previous to the last one. "llistaParamsColors", "llistaParamsRects", "llistaParamsDoubles" and "llistaParamsInts" contain the parameters of each action. Now, I use QMutableListIterators to iterate through the lists but I think that the code can be slighty more efficient because I go through the list sequentally and, also, I need to delete only the last items on each list and not the items in the middle. Here's the code:

    Qt Code:
    1. void MyApp::executeAllUntilPrevious()
    2. {
    3. int aux1, aux2, aux3, aux4;
    4. double auxd1, auxd2, auxd3, auxd4;
    5. QImage imatgeEnganxar;
    6.  
    7. llistaAccions.removeLast();
    8.  
    9. QMutableListIterator<IdentificadorAccions> itAccions(llistaAccions);
    10. QMutableListIterator<QColor> itColors(llistaParamsColors);
    11. QMutableListIterator<QRect> itRects(llistaParamsRects);
    12. QMutableListIterator<double> itDoubles(llistaParamsDoubles);
    13. QMutableListIterator<int> itInts(llistaParamsInts);
    14.  
    15. while(itAccions.hasNext())
    16. {
    17. switch(itAccions.next())
    18. {
    19. case Rotat:
    20. rotat(itColors.next(), itDoubles.next());
    21. break;
    22.  
    23. case Retallat:
    24. retallat(itRects.next());
    25. break;
    26.  
    27. case Pintat:
    28. pintat(itColors.next(), itRects.next());
    29. break;
    30.  
    31. case Copiat:
    32. if (itAccions.hasNext())
    33. imatgeEnganxar = foto -> copiarImatge(itRects.next());
    34. else
    35. itAccions.remove();
    36. break;
    37.  
    38. case Enganxat:
    39. enganxat(itRects.next(), imatgeEnganxar);
    40. break;
    41.  
    42. case Restaurat:
    43. restaurat();
    44. break;
    45.  
    46. case EscalatCm:
    47. auxd1 = itDoubles.next();
    48. auxd2 = itDoubles.next();
    49. canviTamanyCm(auxd1, auxd2);
    50. break;
    51.  
    52. case EscalatPixels:
    53. aux1 = itInts.next();
    54. aux2 = itInts.next();
    55. canviTamanyPixels(aux1, aux2);
    56. break;
    57.  
    58. case CanviatResolucioPixelsCm:
    59. aux1 = itInts.next();
    60. aux2 = itInts.next();
    61. canviResolucioPixelsCm(aux1, aux2);
    62. break;
    63.  
    64. case CanviatResolucioPixelsPolzada:
    65. aux1 = itInts.next();
    66. aux2 = itInts.next();
    67. canviResolucioPixelsPolzada(aux1, aux2);
    68. break;
    69.  
    70. case CanviatMargesCm:
    71. auxd1 = itDoubles.next();
    72. auxd2 = itDoubles.next();
    73. auxd3 = itDoubles.next();
    74. auxd4 = itDoubles.next();
    75. canviTamanyMargesCm(itColors.next(), auxd1, auxd2, auxd3, auxd4);
    76. break;
    77.  
    78. case CanviatMargesPixels:
    79. aux1 = itInts.next();
    80. aux2 = itInts.next();
    81. aux3 = itInts.next();
    82. aux4 = itInts.next();
    83. canviTamanyMargesPixels(itColors.next(), aux1, aux2, aux3, aux4);
    84. }
    85. }
    86.  
    87. //This part is a bit "dirty" and I think that could be achieved with just one sentence...
    88. while(itColors.hasNext())
    89. {
    90. itColors.next();
    91. itColors.remove();
    92. }
    93.  
    94. while(itRects.hasNext())
    95. {
    96. itRects.next();
    97. itRects.remove();
    98. }
    99.  
    100. while(itDoubles.hasNext())
    101. {
    102. itDoubles.next();
    103. itDoubles.remove();
    104. }
    105.  
    106. while(itInts.hasNext())
    107. {
    108. itInts.next();
    109. itInts.remove();
    110. }
    111. }
    To copy to clipboard, switch view to plain text mode 

    Well, I've readed that STL style iterators can be slightly faster than the Java-style iterators (QMutableListIterator). And, inside the STL style iterators, QList::const_iterator is slightly faster than QList::iterator. First of all, do you think that I really need iterators with the code above to obtain a better performance and/or readability? And, in that case, what kind of iterator you think that could fit better in what I need to do: iterate sequentially through the lists and, at the end, delete all the items from the current position until the end. Thanks.

  2. #2
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Question about iterator's choice

    I'm not sure if i understand your question, but i would rather use this kind of code:

    - Create a class for instance IAction, which would be abstract (I think people who went to computer school call this an interface, i'm not sure). In this abstract class i would create a virtual protected method like "virtual int GetType() = 0", to force inheriting classes to implement it. I would then create a public method in it named "int Type() { return GetType(); };".
    - Then, create as many derived classes as you need of action types. For instance, i woud create CAction_Rotate (Implementing IAction), CAction_Restaure (Implementing IAction too) etc... So each derived class implements GetType(), with an unique return value, like an identification of your action. For instance, CAction_Rotate would return 0, defined as a const to "ROTATE".
    - Then in each of your specific action classes you can put parametters (For instance, in CAction_Rotate there would be a public member like "iRotationAngle".
    - Then in your main application, you would just have to maintain a std::stack containing only IAction* pointers.
    - In your loop, you would then be able to get one by one a pointer on the current IAction stack, for instance poping the next action into "pCurrentAction".
    - Then your switch would become "switch (pCurrentAction->Type())".
    - Then on each case, you could change the cast of the pCurrentAction pointer to the required class type, and get parametters for the action. For instance you would have a "case ROTATE : (or case 0 CAction_Rotate* pRotation = (CAction_Rotate*)pCurrentAction; MyRotationFunction(pRotation->iRotationAngle); break;"

    The benefits would be (I guess) that a stack is way faster, you would have only one "stack" for any action type, each one holding it's own parametters.

    But, that's maybe too much complicated for what you're trying to achieve.

    Hope this helps, Good luck and have a nice day!
    Pierre.

    [EDIT:] Just one additionnal stuff, an interesting feature you can add with the way i suggested you, is a Description() method in IAction which returns GetDescription() of course virtual (Based on the same schemas as explained for Type()). It would allow each action to carry a descriptive, translatable information to be displayed for instance in the status bar of your application
    Last edited by hickscorp; 19th December 2006 at 19:49.

  3. The following user says thank you to hickscorp for this useful post:

    Dark_Tower (19th December 2006)

  4. #3
    Join Date
    Jan 2006
    Posts
    105
    Thanks
    38
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Question about iterator's choice

    Thanks hickscorp, the way you have descripted is better, as you say it only has to manage one queue, although it requieres a little more code. Tomorrow I will program it. Have a nice day you too.
    Last edited by Dark_Tower; 20th December 2006 at 00:15.

  5. #4
    Join Date
    Jan 2006
    Posts
    105
    Thanks
    38
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Question about iterator's choice

    Hi again, I have now programmed it as hickscorp descripted. Now I've got a simple question: what kind of list do you think that would be more efficient for the action's list:
    - QList has appending Ammort O(1) because it preallocates extra space on both sides of its internal buffer to allow for fast growth at both ends of the list and index lookup O(1)
    - QLinkedList has appending O(1) and index lookup O(n) but, as I believe, if you access it with an iterator sequentially it's O(1) to acess to the next/previous position.
    I would choose the linked list because I only need to append actions in the list and iterate it sequentially. But the docs says that "For most purposes, QList is the right class to use. Its index-based API is more convenient than QLinkedList's iterator-based API, and it is usually faster than QVector because of the way it stores its items in memory. It also expands to less code in your executable". What do you think?

  6. #5
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Question about iterator's choice

    You're welcome,

    About the QT specific list question, i'm not sure since i'm such a beginner with QT, my skills stops after C++ for now

    But, knowing linked lists basic functionnality, i would choose a simple linked list on pointers (Not much memory allocated for each container since it points to the original object you've created, and since you can get a template one it would compile perfectly to suit your code needs). And, a linked list would be very fast since the current index container holds a pointer on the next one (But again, i don't know how Q* objects work internaly). Be carefull to not use a circular linked list, since if you don't "pop" your actions from it you can end in an infinite loop...

    Bye!
    Last edited by hickscorp; 20th December 2006 at 13:15.

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

    Default Re: Question about iterator's choice

    If you only iterate sequencially, you can go for the linked list, but you won't have any benefits from using it, the regular list will be just as good and is more convenient than using the linked list. Using linked lists practically only makes sense if you intend to insert items in the middle of the list and not at either end.

  8. #7
    Join Date
    Jan 2006
    Posts
    105
    Thanks
    38
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Question about iterator's choice

    Thanks for the suggestion hirckscorp and wysota. Maybe the QList would be less efficent than the QLinkedList in some appends when it has to reallocate more memory (i doubt if it has to copy all the list items again in the new space)

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

    Default Re: Question about iterator's choice

    Quote Originally Posted by Dark_Tower View Post
    (i doubt if it has to copy all the list items again in the new space)
    It moves pointers to the contents, items themselves are not copied.

  10. The following user says thank you to wysota for this useful post:

    Dark_Tower (20th December 2006)

  11. #9
    Join Date
    Jan 2006
    Posts
    105
    Thanks
    38
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Question about iterator's choice

    Thanks wysota is good to know it

Similar Threads

  1. QThread exit()/quit() question
    By TheKedge in forum Qt Programming
    Replies: 1
    Last Post: 28th August 2006, 14:38

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.