Page 1 of 2 12 LastLast
Results 1 to 20 of 23

Thread: QString - Where is find_first_not_of?

  1. #1
    Join Date
    Aug 2008
    Posts
    50
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    5
    Thanked 1 Time in 1 Post

    Default QString - Where is find_first_not_of?

    Hello,

    1) Is there any QString function equivalent to
    Qt Code:
    1. std::string::find_first_of(const std::string & str, 0);
    To copy to clipboard, switch view to plain text mode 
    ?
    I want only 'true' or 'false' return value. I don't want position.

    2) Yes, I know there are QRegExp, but I want fastest solution.

    3) This is my code:
    Qt Code:
    1. bool find_first_not_of(const QString & chars, const QString & text)
    2. {
    3. //return true if text not contains any of char in chars
    4. QString::const_iterator it = text.constBegin();
    5. QString::const_iterator end = text.constEnd();
    6. while(it != end)
    7. {
    8. if(chars.contains(*it) == false)
    9. return true;
    10. ++it;
    11. }
    12.  
    13. return false;
    14. }
    To copy to clipboard, switch view to plain text mode 
    This is code with QRegExp:
    Qt Code:
    1. bool reg_find_first_not_of(const QString & chars, const QString & text)
    2. {
    3. const QRegExp r("[" + QRegExp::escape(chars) + "]+");
    4. return !r.exactMatch(text);
    5. }
    To copy to clipboard, switch view to plain text mode 
    Which code is faster?
    Last edited by lukass; 18th May 2011 at 22:04. Reason: fixed bugs in first and second function

  2. #2
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Wiki edits
    5

    Default Re: QString - Where is find_first_not_of?

    I am not aware of such a function in QString, but why do you don't use find_fist_of? Have you seen QString::toStdString()?

    I would bet, that QRegExp is faster, but why do you not simply run a small benchmark to see what function is faster?

  3. #3
    Join Date
    Aug 2008
    Posts
    50
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    5
    Thanked 1 Time in 1 Post

    Default Re: QString - Where is find_first_not_of?

    Quote Originally Posted by Lykurg View Post
    I am not aware of such a function in QString, but why do you don't use find_fist_of? Have you seen QString::toStdString()?
    Yes, I have seen QString::toStdString(), but I want avoid conversion because:
    1) speed,
    2) unicode characters.

    Quote Originally Posted by Lykurg View Post
    I would bet, that QRegExp is faster, but why do you not simply run a small benchmark to see what function is faster?
    This is another redesign of the wheel, but OK, I do it!

  4. #4
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Thanks
    3
    Thanked 453 Times in 435 Posts
    Wiki edits
    15

    Default Re: QString - Where is find_first_not_of?

    Try this, you can get the std::string from QString, and then operate on it

    Qt Code:
    1. QString text;
    2. std::string str;
    3.  
    4. text.toStdString().find_first_of(str, 0);
    To copy to clipboard, switch view to plain text mode 

  5. #5
    Join Date
    Aug 2008
    Posts
    50
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    5
    Thanked 1 Time in 1 Post

    Default Re: QString - Where is find_first_not_of?

    Quote Originally Posted by Santosh Reddy View Post
    Try this, you can get the std::string from QString, and then operate on it

    Qt Code:
    1. QString text;
    2. std::string str;
    3.  
    4. text.toStdString().find_first_of(str, 0);
    To copy to clipboard, switch view to plain text mode 
    See my #3 post (http://www.qtcentre.org/threads/4172...983#post190983).

    Added after 15 minutes:

    OK folks, I do little benchmark, and winner is:
    -first function.

    Fist function:
    Qt Code:
    1. real 0m0.100s
    2. user 0m0.060s
    3. sys 0m0.013s
    To copy to clipboard, switch view to plain text mode 
    Second function (with QRegExp):
    Qt Code:
    1. real 0m0.146s
    2. user 0m0.100s
    3. sys 0m0.020s
    To copy to clipboard, switch view to plain text mode 
    Last edited by lukass; 18th May 2011 at 22:12.

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

    Default Re: QString - Where is find_first_not_of?

    Quote Originally Posted by lukass View Post
    Hello,

    1) Is there any QString function equivalent to
    Qt Code:
    1. std::string::find_first_of(const std::string & str, 0);
    To copy to clipboard, switch view to plain text mode 
    ?
    I want only 'true' or 'false' return value. I don't want position.
    So compare the result you get to -1 and you'll have your true or false.

    2) Yes, I know there are QRegExp, but I want fastest solution.
    What do you consider "fastest"?

    3) This is my code:
    Qt Code:
    1. bool find_first_not_of(const QString & chars, const QString & text)
    2. {
    3. //return true if text not contains any of char in chars
    4. QString::const_iterator it = text.constBegin();
    5. QString::const_iterator end = text.constEnd();
    6. while(it != end)
    7. {
    8. if(chars.contains(*it) == false)
    9. return true;
    10. ++it;
    11. }
    12.  
    13. return false;
    14. }
    To copy to clipboard, switch view to plain text mode 
    This operation is O(n*m) regardless of how you implement it.

    This is code with QRegExp:
    Qt Code:
    1. bool reg_find_first_not_of(const QString & chars, const QString & text)
    2. {
    3. const QRegExp r("[" + QRegExp::escape(chars) + "]+");
    4. return !r.exactMatch(text);
    5. }
    To copy to clipboard, switch view to plain text mode 
    Which code is faster?
    They are both O(n*m) with the additional overhead in case of the regexp that you need to compile the expression.

    If you run the same code twice or more, the regular expression will be faster (if it is compiled only once). Testing it once (as you did) is not enough. For a single call the difference is neglectible anyway.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Aug 2008
    Posts
    50
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    5
    Thanked 1 Time in 1 Post

    Default Re: QString - Where is find_first_not_of?

    Quote Originally Posted by wysota View Post
    If you run the same code twice or more, the regular expression will be faster (if it is compiled only once). Testing it once (as you did) is not enough. For a single call the difference is neglectible anyway.
    I run four times both functions:
    -first:
    Qt Code:
    1. //[...]
    2. const QString chars =
    3. ",abcdefghijklmnopqrstuwvxyzABCDEFGH IJKLMNOPRSTUWQVXY.Z";
    4.  
    5. bool b = find_first_not_of(chars, txt);
    6. b = find_first_not_of(chars, txt);
    7. b = find_first_not_of(chars, txt);
    8. b = find_first_not_of(chars, txt);
    To copy to clipboard, switch view to plain text mode 

    -second:
    Qt Code:
    1. //[...]
    2. const QString chars =
    3. ",abcdefghijklmnopqrstuwvxyzABCDEFGH IJKLMNOPRSTUWQVXY.Z";
    4.  
    5. bool b = reg_find_first_not_of(chars, txt);
    6. b = reg_find_first_not_of(chars, txt);
    7. b = reg_find_first_not_of(chars, txt);
    8. b = reg_find_first_not_of(chars, txt);
    To copy to clipboard, switch view to plain text mode 

    Time results:
    -first function:
    Qt Code:
    1. real 0m0.185s
    2. user 0m0.147s
    3. sys 0m0.010s
    To copy to clipboard, switch view to plain text mode 
    -second function:
    Qt Code:
    1. real 0m0.376s
    2. user 0m0.330s
    3. sys 0m0.013s
    To copy to clipboard, switch view to plain text mode 

  8. #8
    Join Date
    Apr 2010
    Posts
    769
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11
    Thanks
    1
    Thanked 94 Times in 86 Posts

    Default Re: QString - Where is find_first_not_of?

    You probably shouldn't be using the 'time' function for this; it measures the execution time of the entire application, not just the function in question, and there is overhead associated with program startup, particularly loading of dynamic libraries, that will vary a good deal from one to the other but only incurs a one-time penalty. Loading the system's regex library or the appropriate C++ string handling library, for example, would be one of these. This has nothing to do with the actual function execution time.

    If you want accurate timing, you'll need to either insert system calls within your program, or run it with a profiler that does such things automatically.

    -------------------

    Also, I'm not convinced that looking for the first occurrence of a character not in the given set is faster than looking for the first occurrence of a character in the complementary set. Note, too, that a successful search can probably be coerced to terminate faster if the character set being tested against is ordered so more likely characters occur earlier; a strict alphabetical ordering is almost certainly not optimal. There are character frequency tables scattered around the Web for English and other languages that would probably yield better results, and would be no worse than the sub-optimal ordering you're using now in the worst case.

    On your current code: you're compiling the regex every time you call your function. This consumes a huge amount of time - much more than the actual comparison operation - and it is only necessary to do it once as long as the expression doesn't change.
    Last edited by SixDegrees; 19th May 2011 at 00:26.

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

    Default Re: QString - Where is find_first_not_of?

    Quote Originally Posted by lukass View Post
    I run four times both functions
    But you are recompiling the regular expression with each run.

    Oh... SixDegrees already said that

    Anyway, have a look at QStringMatcher and QByteArrayMatcher. And if you're not interested in Unicode, then use QByteArray, it will be much faster.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  10. #10
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Wiki edits
    17

    Default Re: QString - Where is find_first_not_of?

    My first observation is that the repetition '+' is not required in your regular expression. You are looking only for the first single character:
    Qt Code:
    1. const QRegExp r("[" + QRegExp::escape(chars) + "]");
    To copy to clipboard, switch view to plain text mode 
    Are you always testing for characters that are not in the range A-Z, a-z, a comma, space or period? If so, you can dramatically speed up the regular expression:
    Qt Code:
    1. const QRegExp r("[^A-Za-z,. ]");
    To copy to clipboard, switch view to plain text mode 
    In a test on my machine over a million calls, timed using QTime::elapsed(), I get
    • 4457 ms, reg exp built with chars as is
    • 1741 ms, reg exp built with char ranges; and
    • 338 ms, reg exp built with ranges and made static.
    Qt Code:
    1. QString test("This is the test string and contains a 1 and 2 that are not in the chars");
    2. QString chars = ",abcdefghijklmnopqrstuwvxyzABCDEFGH IJKLMNOPRSTUWQVXY.Z";
    To copy to clipboard, switch view to plain text mode 
    Performance is very strongly affected by variability of the inputs and depends on your exact requirements.

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

    Default Re: QString - Where is find_first_not_of?

    You can further increase the speed if you notice that A-Za-z forms a single range and use QByteArray so that you only work with ASCII. I'd also like to see a speed comparison with strchr() and SIMD CPU instructions.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  12. #12
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Wiki edits
    17

    Default Re: QString - Where is find_first_not_of?

    Quote Originally Posted by wysota View Post
    You can further increase the speed if you notice that A-Za-z forms a single range
    Not in my ASCII table it doesn't.

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

    Default Re: QString - Where is find_first_not_of?

    Quote Originally Posted by ChrisW67 View Post
    Not in my ASCII table it doesn't.
    Aah... true
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  14. #14
    Join Date
    Aug 2008
    Posts
    50
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    5
    Thanked 1 Time in 1 Post

    Default Re: QString - Where is find_first_not_of?

    Quote Originally Posted by SixDegrees View Post
    You probably shouldn't be using the 'time' function for this; it measures the execution time of the entire application, not just the function in question, and there is overhead associated with program startup, particularly loading of dynamic libraries, that will vary a good deal from one to the other but only incurs a one-time penalty. Loading the system's regex library or the appropriate C++ string handling library, for example, would be one of these. This has nothing to do with the actual function execution time.

    If you want accurate timing, you'll need to either insert system calls within your program, or run it with a profiler that does such things automatically.

    -------------------

    Also, I'm not convinced that looking for the first occurrence of a character not in the given set is faster than looking for the first occurrence of a character in the complementary set. Note, too, that a successful search can probably be coerced to terminate faster if the character set being tested against is ordered so more likely characters occur earlier; a strict alphabetical ordering is almost certainly not optimal. There are character frequency tables scattered around the Web for English and other languages that would probably yield better results, and would be no worse than the sub-optimal ordering you're using now in the worst case.

    On your current code: you're compiling the regex every time you call your function. This consumes a huge amount of time - much more than the actual comparison operation - and it is only necessary to do it once as long as the expression doesn't change.
    @SixDegrees: Thanks for the tips!


    Quote Originally Posted by wysota View Post
    Anyway, have a look at QStringMatcher and QByteArrayMatcher. And if you're not interested in Unicode, then use QByteArray, it will be much faster.
    QStringMatcher? QByteArrayMatcher? But I match for characters not for strings.


    Quote Originally Posted by ChrisW67 View Post
    My first observation is that the repetition '+' is not required in your regular expression. You are looking only for the first single character:
    Qt Code:
    1. const QRegExp r("[" + QRegExp::escape(chars) + "]");
    To copy to clipboard, switch view to plain text mode 
    Are you always testing for characters that are not in the range A-Z, a-z, a comma, space or period? If so, you can dramatically speed up the regular expression:
    Qt Code:
    1. const QRegExp r("[^A-Za-z,. ]");
    To copy to clipboard, switch view to plain text mode 
    No, Your terms:
    Qt Code:
    1. const QRegExp r("[" + QRegExp::escape(chars) + "]");
    2. const QRegExp r("[^A-Za-z,. ]");
    To copy to clipboard, switch view to plain text mode 
    give me wrong results.

    The correct terms are:
    Qt Code:
    1. const QRegExp r("[" + QRegExp::escape(chars) + "]+");
    2. const QRegExp r("[A-Za-z\\,\\.\\ ]+");
    To copy to clipboard, switch view to plain text mode 

    This is my new benchmark:
    Qt Code:
    1. #include <QApplication>
    2. #include <QRegExp>
    3. #include <QTime>
    4. #include <iostream>
    5.  
    6. const QString txt =
    7. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    8. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    9. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    10. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    11. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    12. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    13. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    14. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    15. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    16. ;
    17.  
    18.  
    19. bool find_first_not_of(const QString & chars, const QString & text)
    20. {
    21. //return true if text not contains any of char in chars
    22. QString::const_iterator it = text.constBegin();
    23. QString::const_iterator end = text.constEnd();
    24. while(it != end)
    25. {
    26. if(chars.contains(*it) == false)
    27. return true;
    28. ++it;
    29. }
    30.  
    31. return false;
    32. }
    33.  
    34. QRegExp regexp;
    35. bool reg_find_first_not_of(const QString & /*chars*/, const QString & text)
    36. {
    37. return !regexp.exactMatch(text);
    38. }
    39.  
    40. int main(int argc, char *argv[])
    41. {
    42. QApplication a(argc, argv);
    43.  
    44. QTime t;
    45.  
    46. const QString chars =
    47. ",abcdefghijklmnopqrstuwvxyzABCDEFGH IJKLMNOPRSTUWQVXY.Z";
    48.  
    49. //regexp.setPattern("[" + QRegExp::escape(chars) + "]+");
    50. regexp.setPattern("[A-Za-z\\,\\.\\ ]+");
    51.  
    52. bool f1;
    53. bool f2;
    54.  
    55. f1 = find_first_not_of(chars, txt);
    56. t.start();
    57. for(int i = 0; i < 5000; ++i)
    58. f1 = find_first_not_of(chars, txt);
    59. const int e1 = t.elapsed();
    60.  
    61. f2 = reg_find_first_not_of(chars, txt);
    62. t.start();
    63. for(int i = 0; i < 5000; ++i)
    64. f2 = reg_find_first_not_of(chars, txt);
    65. const int e2 = t.elapsed();
    66.  
    67. std::cout << "elapsed for f1 : " << e1 << "ms" << std::endl;
    68. std::cout << "elapsed for f2 QRegExp: " << e2 << "ms" << std::endl;
    69. std::cout << "f1 returns: " << f1 << std::endl;
    70. std::cout << "f2 returns: " << f2 << std::endl;
    71.  
    72. return 0;
    73. }
    To copy to clipboard, switch view to plain text mode 
    And my results:
    Qt Code:
    1. elapsed for f1 : 683ms
    2. elapsed for f2 QRegExp: 1360ms
    3. f1 returns: 0
    4. f2 returns: 0
    To copy to clipboard, switch view to plain text mode 
    As you can see: f2 - QRegExp is slow turtle again.

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

    Default Re: QString - Where is find_first_not_of?

    Quote Originally Posted by lukass View Post
    QStringMatcher? QByteArrayMatcher? But I match for characters not for strings.
    I said "look at" and not "use". Qt is open source, have a look at the source code and implement something that fits your needs.

    No, Your terms:
    Qt Code:
    1. const QRegExp r("[" + QRegExp::escape(chars) + "]");
    2. const QRegExp r("[^A-Za-z,. ]");
    To copy to clipboard, switch view to plain text mode 
    give me wrong results.

    The correct terms are:
    Qt Code:
    1. const QRegExp r("[" + QRegExp::escape(chars) + "]+");
    2. const QRegExp r("[A-Za-z\\,\\.\\ ]+");
    To copy to clipboard, switch view to plain text mode 
    These are two totally different expressions. One is an "accepting" expression the other is a "rejecting" one so the function logic has to differ, you can't just replace the expresions.

    This is my new benchmark:
    (...)
    As you can see: f2 - QRegExp is slow turtle again.
    Using QTime::elapsed() for a benchmark is a silly thing to do.

    To me it seems the best solution would be some sort of radix search using MMX or similar. For multicore/manycore a solution using multiple threads would probably be fastest. OpenCL would also handle it nicely.
    Last edited by wysota; 19th May 2011 at 13:21.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  16. #16
    Join Date
    Aug 2008
    Posts
    50
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    5
    Thanked 1 Time in 1 Post

    Default Re: QString - Where is find_first_not_of?

    Quote Originally Posted by wysota View Post
    To me it seems the best solution would be some sort of radix search using MMX or similar. For multicore/manycore a solution using multiple threads would probably be fastest. OpenCL would also handle it nicely.
    No, I don't need such low level solution, but thanks for tips.

    I changed my benchmark to use QSet for characters:
    Qt Code:
    1. #include <QApplication>
    2. #include <QRegExp>
    3. #include <QTime>
    4. #include <iostream>
    5. #include <QSet>
    6.  
    7. const QString txt =
    8. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    9. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    10. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    11. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    12. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    13. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    14. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    15. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    16. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    17. ;
    18.  
    19.  
    20. bool find_first_not_of(const QString & chars, const QString & text)
    21. {
    22. //return true if text not contains any of char in chars
    23. QString::const_iterator it = text.constBegin();
    24. QString::const_iterator end = text.constEnd();
    25. while(it != end)
    26. {
    27. if(chars.contains(*it) == false)
    28. return true;
    29. ++it;
    30. }
    31.  
    32. return false;
    33. }
    34.  
    35. bool find_first_not_of(const QSet<QChar> & chars, const QString & text)
    36. {
    37. //return true if text not contains any of char in chars
    38. QString::const_iterator it = text.constBegin();
    39. QString::const_iterator end = text.constEnd();
    40. while(it != end)
    41. {
    42. if(chars.contains(*it) == false)
    43. return true;
    44. ++it;
    45. }
    46.  
    47. return false;
    48. }
    49.  
    50. QRegExp regexp;
    51. bool reg_find_first_not_of(const QString & /*chars*/, const QString & text)
    52. {
    53. return !regexp.exactMatch(text);
    54. }
    55.  
    56. int main(int argc, char *argv[])
    57. {
    58. QApplication a(argc, argv);
    59.  
    60. QTime t;
    61.  
    62. const QString chars =
    63. ",abcdefghijklmnopqrstuwvxyzABCDEFGH IJKLMNOPRSTUWQVXY.Z";
    64.  
    65. QSet<QChar> chars_set;
    66. for(int i = 0; i < chars.size(); ++i)
    67. chars_set.insert(chars.at(i));
    68.  
    69. //regexp.setPattern("[" + QRegExp::escape(chars) + "]+");
    70. regexp.setPattern("[A-Za-z\\,\\.\\ ]+");
    71.  
    72. bool f1;
    73. bool f2;
    74.  
    75. f1 = find_first_not_of(chars_set, txt);
    76. t.start();
    77. for(int i = 0; i < 5000; ++i)
    78. f1 = find_first_not_of(chars_set, txt);
    79. const int e1 = t.elapsed();
    80.  
    81. f2 = reg_find_first_not_of(chars, txt);
    82. t.start();
    83. for(int i = 0; i < 5000; ++i)
    84. f2 = reg_find_first_not_of(chars, txt);
    85. const int e2 = t.elapsed();
    86.  
    87. std::cout << "elapsed for f1 : " << e1 << "ms" << std::endl;
    88. std::cout << "elapsed for f2 QRegExp: " << e2 << "ms" << std::endl;
    89. std::cout << "f1 returns: " << f1 << std::endl;
    90. std::cout << "f2 returns: " << f2 << std::endl;
    91.  
    92. return 0;
    93. }
    To copy to clipboard, switch view to plain text mode 
    and results are better:
    Qt Code:
    1. elapsed for f1 : 412ms
    2. elapsed for f2 QRegExp: 1373ms
    3. f1 returns: 0
    4. f2 returns: 0
    To copy to clipboard, switch view to plain text mode 

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

    Default Re: QString - Where is find_first_not_of?

    Quote Originally Posted by lukass View Post
    No, I don't need such low level solution, but thanks for tips.
    Why do you think those solutions are low-level?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  18. #18
    Join Date
    Aug 2008
    Posts
    50
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    5
    Thanked 1 Time in 1 Post

    Default Re: QString - Where is find_first_not_of?

    Quote Originally Posted by wysota View Post
    Why do you think those solutions are low-level?
    Because you wrote 'MMX'.

    I need such function as 'find_first_not_of' for validating substrings of IRC messages in real time.
    Last edited by lukass; 19th May 2011 at 14:11.

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

    Default Re: QString - Where is find_first_not_of?

    Here is a test using radix search vs naive search, I think the results are quite impressive.

    Qt Code:
    1. #include <QtDebug>
    2. #include <QByteArray>
    3. #include <qtest.h>
    4.  
    5. struct TrieNode {
    6. TrieNode *left;
    7. TrieNode *right;
    8. TrieNode(){ left = right = 0; }
    9. ~TrieNode() { delete left; delete right; }
    10. };
    11.  
    12. TrieNode* buildTrie(const QByteArray& chars) {
    13. TrieNode *root = new TrieNode;
    14. const int s = chars.size();
    15. for(int i=0;i<s;++i){
    16. TrieNode *current = root;
    17. register int level = 8;
    18. register int ch = chars.at(i);
    19. while(level-->0) {
    20. int bit = ch & 0x1;
    21. ch = ch >> 1;
    22. if(bit==0){
    23. if(!current->left)
    24. current->left = new TrieNode;
    25. current = current->left;
    26. } else {
    27. if(!current->right)
    28. current->right = new TrieNode;
    29. current = current->right;
    30. }
    31. }
    32.  
    33. }
    34. return root;
    35. }
    36.  
    37. bool inTrie(TrieNode *trie, char ch) {
    38. int level = 8;
    39. while(trie && level-->0) {
    40. int bit = ch & 0x1;
    41. ch >>=1;
    42. trie = bit ? trie->right : trie->left;
    43. }
    44. if(!trie) return false;
    45. return true;
    46. }
    47.  
    48. int findFirstNotOf(TrieNode *trie, const QByteArray &haystack){
    49. const int s = haystack.size();
    50. for(int i=0;i<s;++i){
    51. char ch = haystack.at(i);
    52. if(!inTrie(trie, ch)) return i;
    53. }
    54. return -1;
    55. }
    56.  
    57. int findFirstNotOf(const QByteArray &needle, const QByteArray &haystack) {
    58. const int hs = haystack.size();
    59. for(int i=0;i<hs;++i){
    60. if(!needle.contains(haystack.at(i)))
    61. return i;
    62. }
    63. return -1;
    64. }
    65.  
    66. class Benchmark : public QObject {
    67. Q_OBJECT
    68. public:
    69. Benchmark() {
    70. ba="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,. ";
    71. haystack = "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam";
    72.  
    73. }
    74. private slots:
    75. void radixTest() {
    76. TrieNode *trie = buildTrie(ba);
    77. QBENCHMARK {
    78. findFirstNotOf(trie, haystack);
    79. }
    80. delete trie;
    81. }
    82. void naiveTest() {
    83. QBENCHMARK {
    84. findFirstNotOf(ba, haystack);
    85. }
    86. }
    87. private:
    88. QByteArray ba, haystack;
    89. };
    90.  
    91. QTEST_MAIN(Benchmark)
    92.  
    93. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 

    And results:
    ********* Start testing of Benchmark *********
    Config: Using QTest library 4.7.2, Qt 4.7.2
    PASS : Benchmark::initTestCase()
    RESULT : Benchmark::radixTest():
    0.0000045 msecs per iteration (total: 76, iterations: 16777216)
    PASS : Benchmark::radixTest()
    RESULT : Benchmark::naiveTest():
    0.0076 msecs per iteration (total: 63, iterations: 8192)
    PASS : Benchmark::naiveTest()
    PASS : Benchmark::cleanupTestCase()
    Totals: 4 passed, 0 failed, 0 skipped
    ********* Finished testing of Benchmark *********
    Anyone wants to beat that?

    The larger the needle, the better the radix trie will perform against other algorithms. The performance would be even better with SIMD approach.

    Edit: Actually it's more a binary search rather than radix search since the nodes are not compacted when having only one child.
    Last edited by wysota; 19th May 2011 at 14:38.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  20. #20
    Join Date
    Aug 2008
    Posts
    50
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    5
    Thanked 1 Time in 1 Post

    Default Re: QString - Where is find_first_not_of?

    Quote Originally Posted by wysota View Post
    Anyone wants to beat that?
    Not sure, but I have probably faster code:
    - I added unsigned to 'int' variables where are bitwise operators - right shift, because operation right shift on signed variable has portability issues,
    - changed haystack to QString,
    - added QSet instead of QByteArray needle to naiveTest.

    Look at this:
    Qt Code:
    1. #include <QtDebug>
    2. #include <QByteArray>
    3. #include <QTest>
    4.  
    5. struct TrieNode {
    6. TrieNode *left;
    7. TrieNode *right;
    8. TrieNode(){ left = right = 0; }
    9. ~TrieNode() { delete left; delete right; }
    10. };
    11.  
    12. TrieNode* buildTrie(const QByteArray& chars) {
    13. TrieNode *root = new TrieNode;
    14. const int s = chars.size();
    15. for(int i=0;i<s;++i){
    16. TrieNode *current = root;
    17. register int level = 8;
    18. register unsigned int ch = chars.at(i);
    19. while(level-->0) {
    20. int bit = ch & 0x1;
    21. ch = ch >> 1;
    22. if(bit==0){
    23. if(!current->left)
    24. current->left = new TrieNode;
    25. current = current->left;
    26. } else {
    27. if(!current->right)
    28. current->right = new TrieNode;
    29. current = current->right;
    30. }
    31. }
    32.  
    33. }
    34. return root;
    35. }
    36.  
    37. bool inTrie(TrieNode *trie, unsigned char ch) {
    38. int level = 8;
    39. while(trie && level-->0) {
    40. int bit = ch & 0x1;
    41. ch >>=1;
    42. trie = bit ? trie->right : trie->left;
    43. }
    44. if(!trie) return false;
    45. return true;
    46. }
    47.  
    48. int findFirstNotOf(TrieNode *trie, const QString & hs){
    49. const QByteArray haystack = hs.toAscii();
    50. const int s = haystack.size();
    51. for(int i=0;i<s;++i){
    52. char ch = haystack.at(i);
    53. if(!inTrie(trie, ch)) return i;
    54. }
    55. return -1;
    56. }
    57.  
    58. int findFirstNotOf(const QSet<char> & needle, const QString & hs) {
    59. const QByteArray haystack = hs.toAscii();
    60. const int s = haystack.size();
    61. for(int i=0;i<s;++i){
    62. if(!needle.contains(haystack.at(i)))
    63. return i;
    64. }
    65. return -1;
    66. }
    67.  
    68. class Benchmark : public QObject {
    69. Q_OBJECT
    70. public:
    71. Benchmark() {
    72. ba="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,. ";
    73.  
    74. haystack =
    75. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    76. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    77. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    78. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    79. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    80. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    81. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    82. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    83. "ac, hendrerit nec justo. Nullam tristique consequat sem, id placerat eros egestas vitae. Donec imperdiet, metus id feugiat rhoncus, sem risus condimentum diam, eget volutpat diam dolor in dui. Proin mi quam,"
    84. ;
    85. }
    86. private slots:
    87. void radixTest() {
    88. TrieNode *trie = buildTrie(ba);
    89. QBENCHMARK {
    90. findFirstNotOf(trie, haystack);
    91. }
    92. delete trie;
    93. }
    94. void naiveTest() {
    95. QSet<char> chars_set;
    96. for(int i = 0; i < ba.size(); ++i)
    97. chars_set.insert(ba.at(i));
    98.  
    99. QBENCHMARK {
    100. findFirstNotOf(chars_set, haystack);
    101. }
    102. }
    103. private:
    104. QString haystack;
    105. };
    106.  
    107. QTEST_MAIN(Benchmark)
    108.  
    109. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 
    And results:
    ********* Start testing of Benchmark *********
    Config: Using QTest library 4.7.3, Qt 4.7.3
    PASS : Benchmark::initTestCase()
    RESULT : Benchmark::radixTest():
    0.12 msecs per iteration (total: 63, iterations: 512)
    PASS : Benchmark::radixTest()
    RESULT : Benchmark::naiveTest():
    0.088 msecs per iteration (total: 91, iterations: 1024)
    PASS : Benchmark::naiveTest()
    PASS : Benchmark::cleanupTestCase()
    Totals: 4 passed, 0 failed, 0 skipped
    ********* Finished testing of Benchmark *********

Similar Threads

  1. Replies: 8
    Last Post: 25th November 2010, 12:40
  2. With QString create a QString&
    By avis_phoenix in forum Newbie
    Replies: 1
    Last Post: 21st April 2010, 23:05
  3. Replies: 4
    Last Post: 1st February 2010, 15:21
  4. Replies: 4
    Last Post: 31st January 2008, 21:44
  5. how to copy part of QString to anothe QString
    By nass in forum Qt Programming
    Replies: 1
    Last Post: 26th March 2007, 20:05

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.