Which option is faster...

Raphaël Jakse raphael.jakse at gmail.com
Mon Aug 5 18:36:58 PDT 2013


Le 05/08/2013 15:59, jicman a écrit :
>
> Greetings!
>
> I have this code,
>
> foreach (...)
> {
>
>    if (std.string.tolower(fext[0]) == "doc" ||
>      std.string.tolower(fext[0]) == "docx" ||
>      std.string.tolower(fext[0]) == "xls" ||
>      std.string.tolower(fext[0]) == "xlsx" ||
>      std.string.tolower(fext[0]) == "ppt" ||
>      std.string.tolower(fext[0]) == "pptx")
>     continue;
> }
>
> foreach (...)
> {
>    if (std.string.tolower(fext[0]) == "doc")
>      continue;
>    if (std.string.tolower(fext[0]) == "docx")
>      continue;
>    if (std.string.tolower(fext[0]) == "xls")
>      continue;
>    if (std.string.tolower(fext[0]) == "xlsx")
>      continue;
>    if (std.string.tolower(fext[0]) == "ppt")
>      continue;
>    if (std.string.tolower(fext[0]) == "pptx")
>     continue;
>    ...
>    ...
> }
>
> thanks.
>
> josé


Like others said, writing if( ...) continue; if(...) continue; versus 
if(... ||  ...) continue; is not the problem in the code.
Computing the lower case of the string for each comparison is a greater 
problem that can be spotted at the first glance. Storing the value in a 
variable and then using this variables in comparisons would be better.

Both versions of your code should be equivalent, though this should be 
verified.

I would suggest another way of doing this:

       switch(std.string.tolower(fext[0])) {
          case "doc":
          case "docx":
          case "xls":
          case "xlsx":
          case "ppt":
          case "pptx":
             continue;
          default:
            // do something else
       }

This way of writing your code seems far more readable and elegant to me.

Even more concise:
switch(std.string.tolower(fext[0])) {
    case "doc","docx","xls","xlsx","ppt","pptx":
       continue;
    default:
       // do something else
}

Much like what morarch_dodra proposed, I guess.

But notice that tolower is deprecated in current D2 version, toLower 
should be used instead. If you still use D1, maybe a better thing to do 
before considering such optimization would be opting for D2.

I would also suggest avoiding usage of continue if you don't need it. 
Here, it is likely that you can write something more structured like:

import std.string : toLower

// ...

foreach(...) {
    switch(fext[0].toLower) {
       case "doc","docx","xls","xlsx","ppt","pptx":
          // do what is to be done here with these cases, or nothing
          break;
       default:
          // do something for other cases
    }
}

If you need to use fext[0].toLower in any case, I would suggest you 
write this kind of code instead:


import std.string : toLower

// ...

auto ext = fext[0].toLower;
switch(ext) {
    case "doc","docx","xls","xlsx","ppt","pptx":
       // do what is to be done here with these cases, or nothing
       // use ext instead of fext[0].toLower, if needed
       break;
    default:
       // do something for other cases
       // use ext instead of fext[0].toLower, if needed
}


auto ext = fext[0].toLower; should be placed before the foreach loop if 
fext[0] isn't changed in the loop (avoid computing a value more than one 
time when it is possible, though thinking before applying this rule or 
any other rule is not forbidden).

There might exist solutions that could be faster, like testing the first 
letter before the second / using the length of the string / using finite 
state machine to save tests, but beware of the maintainability of your 
code and if you go into this, triple check that these solutions are 
indeed more efficient in terms of execution.

See morarch_dodra, JS, bearophile and others posts for more precise 
information.

If this part of your code is not known to be a bottleneck, I would opt 
for readability / elegance over over-optimization and for this 
particular case, I would trust the compiler for optimizing enough with 
the switch version of the code (though it is not more than a opinion here).





More information about the Digitalmars-d-learn mailing list