Comparison of IF with Command Group and IFF

Jun 2, 2008
339
2
Newton, MA
What are the relative merits of the following two forms of a conditional test?

if condition (
command1
command2
...
lastcommand
)

iff condition then
command1
command2
...
lastcommand
endiff

In most situations, both forms would produce identical results. Is there anything to favor one over the other?

When processing of the command separator is turned off by setdos /x-5, command grouping will not work, since (as I discovered by tripping over it) TCC converts the entered text into a single command line with the command separator between the individual commands.

That, I discovered, is also a problem with the FOR command when one wants to execute multiple commands. However, I have now verified that one can overcome the problem by making the command run by FOR be a subroutine call. The subroutine can have mulitple commands.

The first form also has a problem if the closing parenthesis character appears in one of the commands in an unbalanced form, e.g., "echo (a or )" works but "echo A)" terminates the group.
 

samintz

Scott Mintz
May 20, 2008
1,475
15
Solon, OH, USA
Compound statements are executed as a single statement. If you try to debug a script using BDEBUGGER, it will step over the entire command group. Whereas the IFF statement will allow you to execute the individual statements within the IFF/ENDIFF.
 
Jun 2, 2008
339
2
Newton, MA
Good point. That's related to my comment that TCC internally converts the set of command to a one-line command of the form

command1 & command2 & ... & lastcommand

After I had run SETDOS /X-5 in a batch file with the multi-line command group, I got an error message showing all the ampersand characters, which I had not typed.

I could also have asked the question with the first command written as

if condition ( command1 & command2 & ... & lastcommand )

since that is what TCC actually has.

I'm mainly wondering about the relative efficiency of the two version. Of course, the IFF command also supports an ELSE section.

In a batch file that needed to process lines from a file that may very well contain ampersands and could even have redirection characters, I turned of that processing with SETDOS /X-56. (In fact, the function of the code was to report lines that contained those characters and other problems.) The FOR command with a long, multi-line command group immediately failed! I rewrote the program to use DO instead, which does not need multiple commands on a line. Now I realize that I could have put the complex FOR code in a subroutine and called it from the FOR command. I just experimented with that in a test file, and it worked quite nicely.
 
Jay, there is also an ELSE in the If version, e.g. like this:
Code:
Set jobfile="%1"
If %jobfile% EQU "" (
  Echo Aufruf: UniXAnsi Eingabedatei U/M (%helpparam%)
  Goto :EOF
) Else (
  Echo jobfile=%jobfile%
    Echo Full :%~f1
    Echo Name :%~n1
    Echo Ext  :%~x1
    Echo Drive:%~d1
    Echo Path :%~pjobfile
)
But you have to write the code in several lines and carefully count the brackets.
I find the TCC-IFF version much clearer and more comfortable than the curious CMD/BATCH version.
 
Jun 2, 2008
339
2
Newton, MA
Thanks for pointing that out; I was not aware of that. I see that it is documented, but not prominently.

In fact, I prefer the IFF-THEN-ELSE-ENDIFF for its clear structure. I was just wondering if there was any performance reason to use one instead of the other. No one has commented on that, so I'm assuming that it makes little difference.

I am glad that while researching this I discovered the trick of using a subroutine with the FOR command to achieve the effect of multiple commands even when the command separator function is turned off.
 
May 20, 2008
11,046
90
Syracuse, NY, USA
There's a difference in speed but it's not great. Here's a simple-minded test that uses NOOP, a plugin command that does nothing. It compares ( noop & noop & noop & noop & noop & noop ) to the six-line version ... wrapped in IF/IFF 1 == 1 ... wrapped in DO i=1 to 100000. The results are times, relative to the first one; so these are in order of increasing speed.

Code:
v:\> iffif.btm
IFF with multiple lines: 1.000
IF with multiple lines: 0.986
IF with compound statement: 0.970
IFF with compound statemant: 0.960
 
May 20, 2008
11,046
90
Syracuse, NY, USA
Here's a more sophisticated time comparison. For each of the 4 cases, I timed then both WITH the IF/IFF construction and WITHOUT it ... then subtracted to see how much adding the IF/IFF contributed. For example,

Code:
set millisecs=`%@word[0,%@timer[1,ms]]`

echos IF with multiple lines:
timer /q /1 on
do i=1 to 10000
if 1 == 1 (
echos
echos
echos
echos
echos
echos
)
enddo
set with=%millisecs

timer /q /1 on
do i=1 to 10000
echos
echos
echos
echos
echos
echos
enddo
set without=%millisecs
echo ^s%@eval[%with-%without]

The results are a little surprising. The numbers below are times (the (%with-%without) difference mentioned above) so the ones with smaller numbers are the faster ones. And since I've tried to disregard extraneous stuff, the differences are greater (about 15% between fastest and slowest). I've also used ECHOS instead of NOOP so a plugin wouldn't be needed. And I've attached the BTM.

Code:
v:\> iffif.btm
IFF with multiple lines: 2061
IF with multiple lines: 1869
IF with compound statement: 2169
IFF with compound statemant: 2070
 

Attachments

  • iffif.btm
    1.3 KB · Views: 27