Page 1 of 1

multiple string equality testing

Posted: Thu Oct 26, 2006 10:57 am
by altimac
I encounter a frequent situation and i never knows which implementation is the fastest:

if have to test in an NSString* pattern is not equal to several other NSStrings. Currently i'm balanced between these 2 implementations:

NSString* pattern = @"XXXXXXX";
if(![pattern isEqualToString:a] && ![pattern isEqualToString:b] && ![pattern isEqualToString:c] && ....)
[self doSomeWork];

and

NSSet* forbiddenStringsSet = [NSSet setWithObjects:a,b,c,.......,nil]; (can be STATICALLY SET, ONCE FOR ALL !!!! of course)
if(![forbiddenStringsSet containsObject:pattern])
[self doSomeWork];


Of course, it all depends on the number of strings to tests...
What is your opinion?
Is it possible to have a graph, something like the famous for() vs NSEnumerator ... ? i have no idea how to implement such a test :)

thanks!

Re: multiple string equality testing

Posted: Tue Oct 31, 2006 11:20 am
by Nat!
Well yes, it depends on the number of strings you want to match against.

To simplify your code a bit (this removes the negation, it's easier for my head)

Code: Select all

if( [pattern isEqualToString:a])
   continue;
if( [pattern isEqualToString:b])
   continue;
if( [pattern isEqualToString:c])
   continue;

[self doStuff];


Some things to consider:
If "pattern" were static and the number of comparisons is statistically (!) large (>3 i would say on a hunch), you could IMP cache isEqualToString:.

If "a", "b", "c" are static you can use hash to your advantage. Precalculate the hash values into a C-Array and compare those. Only if a hash matches, check with isEqualToString:. You could use the imp caching idea from above, but make sure that a, b, c are of the same class using NSAsserts. (This is basically like an NSSet, just likely to be faster for not too many abcs)

You could use a NSHashTable instead of NSSet.



To measure something like this is easy.

Write a loop, wrapped in NSLog statements

Code: Select all

NSLog( @"start");
   for( i = 0; i< 100000; i++)
   {
      // test code
   }
   NSLog( @"stop");

Note the time that is spent between @start and @stop, that's it.

Posted: Tue Oct 31, 2006 11:39 am
by altimac
thanks Nat!

I knew you would be the one to ask!