-4

Is there a faster alternative approach to the following code:

 bool isAlphabeticOnly(String strin)
        {
            foreach (char c in strin)
            {
                if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z'))
                    return false;
            }
            return true;
        }

Thanks in advance.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
Jogi
  • 1
  • 2
  • 14
  • 29
  • 3
    Please provide your benchmarking code, so that people can test their alternative suggestions against yours. – Heinzi May 31 '16 at 15:44
  • Probably not _significantly_ faster. - you short circuit, and are doing fast comparisons. Are you sure your logic is right? – D Stanley May 31 '16 at 15:44
  • 1
    Also, is this a bottleneck in your app? Why are you worried about its performance when there are likely other parts of your app that _can_ be made faster? – D Stanley May 31 '16 at 15:46
  • 3
    Are you sure that you want "Résumé" to be a "non-alphabetic" word? – Heinzi May 31 '16 at 15:46
  • @Heinzi what do you mean by benchmarking code? – Jogi May 31 '16 at 15:49
  • 2
    @RehanKhan: You are asking whether there is a faster alternative to your code. So I assumed that you *measured* the speed of your code (this is what benchmarking does) and determined it to be insufficient. Here's an example: http://stackoverflow.com/q/1047218/87698 – Heinzi May 31 '16 at 15:51
  • @DStanley In the above code, I am checking if a string contains only alphabetic characters and its giving me the correct output. What do you mean by am I sure my logic is right? – Jogi May 31 '16 at 15:58
  • @DStanley There must be other parts of my app that i can make faster but I've to start from somewhere - correct? – Jogi May 31 '16 at 15:59
  • 2
    Yes - _you start at the slowest part_. You can't make a bicycle faster by making the seat more aerodynamic. Get a decent profiler, determine which part of your app is the slowest, and tackle that first. – D Stanley May 31 '16 at 16:01
  • 1
    @RehanKhan : _Résumé_ **!=** _Resume_. – Visual Vincent May 31 '16 at 16:06
  • 2
    @RehanKhan Logic with ANDs, ORs NOTs, and `<`/`>` can be tricky. Is's very easy to get the logic wrong and get bad results. I'm not saying it _is_ wrong - just making sure you've thoroughly tested all edge cases. – D Stanley May 31 '16 at 16:08
  • @DStanley Almost all my logics in this app involve ANDs, ORs, NOTs and `>`. How to determine slowest part? By clicking `Debug All` and run each command at a time and note the time taken for completion of its execuation? – Jogi May 31 '16 at 16:20

2 Answers2

4

Well, this implementation is a bit faster (but less readable)

bool isAlphabeticOnly(String strin) {
  // comparison with 0 - "i >= 0" - is faster than with strin.Length
  for (int i = strin.Length - 1; i >= 0; --i) {
    char c = strin[i];

    if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z'))
      return false;
  }

  return true;
}

At my workstation (.net 4.5, IA64, Core i5 3.2GHz) average times are

  Initial 2100 ms
  This    1600 ms

Measuring

 // Yes, very long string 
 String test = new String('p', 100000000) + new String('Q', 100000000);

 Stopwatch sw = new Stopwatch();

 sw.Start();

 isAlphabeticOnly(test);

 sw.Stop();

However, if you experience real performance problems, it's not isAlphabeticOnly where you should solve it.

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • Thanks for your help. I've `IsDigitsOnly` , `isPunctuation`, & `isAlphaNumberic` alongwith `isAlphabeticOnly`. I'll implement your suggested logic (`comparison with 0 - "i >= 0" - is faster than with strin.Length`) in all of them. What else I should check for better performance? – Jogi May 31 '16 at 16:07
  • @Rehan Khan: you can try using `Parallel.ForEach` and alike, but this will do on *large* strings only (multithreading adds *overhead*) – Dmitry Bychenko May 31 '16 at 16:15
  • Used `.NET Profiler` to find out the slowest part of my code. Changed its logic and its performance is at least 85% gone faster. – Jogi Jun 01 '16 at 15:53
0

I only tested with Cat - you need to put all letters in
Not sure if this is faster but worth testing

HashSet<char> hsAz = new HashSet<char> { 'a', 't', 'C' };
bool isAlphabeticOnlyHash(String strin)
{
    for (int i = strin.Length - 1; i >= 0; --i) 
    {
        if (!hsAz.Contains(strin[i]))
            return false;
    }
    return true;
}
paparazzo
  • 44,497
  • 23
  • 105
  • 176
  • 1
    Sorry, I've tried and got `7100` milliseconds (while the initial solution has `2100`) at my workstation. It was worth testing, but in *this particular case* computing hash is slower operation than direct comparison. – Dmitry Bychenko May 31 '16 at 16:24
  • @RehanKhan What part of "Not sure if this is faster but worth testing" was not clear? – paparazzo May 31 '16 at 16:25
  • @RehanKhan You ingrate. You asked a question and I put out a valid idea to try and was open about that. This is a free site and we are not obligated to benchmark. – paparazzo May 31 '16 at 16:32
  • @Paparazzi Sorry I missed reading "Not sure if this is faster but worth testing" part of your answer. Thanks for your time and answer. Appreciate it mate. – Jogi May 31 '16 at 16:51