Board index » delphi » Couple of questions.

Couple of questions.

First, is there a speed difference between these two code segments:

WHILE (Counter > 1) AND NOT(Flag) DO
        BEGIN
                Counter := Counter - 1;
                Flag := StrVar[Counter] = 'a'
        END;

                or

WHILE (Counter > 1) AND (StrVar[Counter] <> 'a') DO
        Counter := Counter - 1;

Also, are Halt and Exit procedures considered one of the deadly sins?
Thanks for all help,

Joe Mumbauer.  Mu...@Erols.COM

 

Re:Couple of questions.


Quote
> Also, are Halt and Exit procedures considered one of the deadly sins?

I'm sure: NO!
Structured programming doesn't mean, that you have to write difficult
structures, if you can do it much easier. You may use 'goto' if you like it.

Andras

Re:Couple of questions.


Quote
Joe Mumbauer wrote in message

<01bdaeca$0d89bf80$3aa1a...@Mumbs.Erols>...

Quote
>First, is there a speed difference between these two code segments:

>WHILE (Counter > 1) AND NOT(Flag) DO
> BEGIN
>  Counter := Counter - 1;
> Flag := StrVar[Counter] = 'a'
> END;

> or

>WHILE (Counter > 1) AND (StrVar[Counter] <> 'a') DO
> Counter := Counter - 1;

Depends on how Flag is initialised. In the second case, Counter will
be such that StrVar[Counter]='a' on exit, assuming that such an
element of StrVar exists and that Counter was initialised to a value
greater than or equal to the index of that element.

In the former case, however - and assuming that Flag is initialised to
False - then the loop will only work if Counter was initialised to a
value strictly greater than the index being sought.

If you initialise Flag to StrVar[Counter] = 'a' the loops will
function identically but the second version is more elegant, compiles
to less code and will be easier to maintain (if you want to search for
'b' instead, you only have to change one line instead of two).

Quote
>Also, are Halt and Exit procedures considered one of the deadly sins?

I wouldn't think so, but people claiming that they are  may be
committing the sin of Pride, which is one.

FP

Re:Couple of questions.


Quote
Frank Peelo wrote:
> Joe Mumbauer wrote in message
> <01bdaeca$0d89bf80$3aa1a...@Mumbs.Erols>...
> >First, is there a speed difference between these two code segments:

> >WHILE (Counter > 1) AND NOT(Flag) DO
> > BEGIN
> >  Counter := Counter - 1;
> > Flag := StrVar[Counter] = 'a'
> > END;

> > or

> >WHILE (Counter > 1) AND (StrVar[Counter] <> 'a') DO
> > Counter := Counter - 1;

> Depends on how Flag is initialised. In the second case, Counter will
> be such that StrVar[Counter]='a' on exit, assuming that such an
> element of StrVar exists and that Counter was initialised to a value
> greater than or equal to the index of that element.

> In the former case, however - and assuming that Flag is initialised to
> False - then the loop will only work if Counter was initialised to a
> value strictly greater than the index being sought.

> If you initialise Flag to StrVar[Counter] = 'a' the loops will
> function identically but the second version is more elegant, compiles
> to less code and will be easier to maintain (if you want to search for
> 'b' instead, you only have to change one line instead of two).

That is not right at all. In the last case, both loops will be entered the
same often in the last case, but they do not take the same time. The
runtime ratio of these two loops is about 2 to 3 in favour of the second
one. So, the second is not only more elegant but also faster.

I ghink this really hits the question, doesn't it?

All the best

Hans J?rg Brinksmeyer

Re:Couple of questions.


Quote
Hans J?rg Brinksmeyer wrote in message

<35ABD839.2F67F...@physik.uni-marburg.de>...

Quote
>Frank Peelo wrote:
>> If you initialise Flag to StrVar[Counter] = 'a' the loops will
>> function identically but the second version is more elegant,
compiles
>> to less code and will be easier to maintain (if you want to search
for
>> 'b' instead, you only have to change one line instead of two).

>That is not right at all. In the last case, both loops will be
entered the
>same often in the last case, but they do not take the same time. The
>runtime ratio of these two loops is about 2 to 3 in favour of the
second
>one. So, the second is not only more elegant but also faster.

>I ghink this really hits the question, doesn't it?

Well, I didn't comment on speed but apart from that you seem to be
agreeing with me. I said the second version is better [more elegant,
smaller object code], you say that's wrong, the second version is
better. Am I missing something here?

There is a subtle difference in behaviour between the two code
fragments, depending on how Flag is initialised. ISTM that at most one
of the behaviours can be correct. "The speed of a nonworking program
is irrelevant", so I would have thought the question was about how to
determine which fragment worked right.

FP

Re:Couple of questions.


In article <01bdaeca$0d89bf80$3aa1a...@mumbs.erols>,

Quote
Joe Mumbauer <Mu...@Erols.COM> wrote:
>First, is there a speed difference between these two code segments:

>WHILE (Counter > 1) AND NOT(Flag) DO
>    BEGIN
>            Counter := Counter - 1;
>            Flag := StrVar[Counter] = 'a'
>    END;

>            or

>WHILE (Counter > 1) AND (StrVar[Counter] <> 'a') DO
>    Counter := Counter - 1;

Borland Pascal by default performs boolean arithmetic with sort circuit
method. With and that means that if the first part is false then the
second part is not evaluated at all. This is faster and allows nicer
code, i.e. one does not need so many of those flags. On standard Pascal
the evaluation is complete i.e. both parts are always evaluated.

Now if there was complete evaluation and if there was also range
checking and StrVal began from index 2 then the second would cause an
error as it tried to access index StrVal[1]. But so would there be in
the first as there is no separate test for counter when the flag is
evaluated. It should be if counter>1 then flag:=.... to make a
difference.

I assume StrVal is a string so it actually begins at index 0 (the length
byte) so there is no problem.

Note that sometimes the fact that the length byte is at index 0 can be
used nicely, like when one wants to remove trailing blanks:

while st[length(st)]=' ' do dec(byte(st[0]);

No separate terminating condition will be needed for strings that are
empty or become empty as then the test will be if #0=' ' which is false.
(removing trailing nulls is a different case)

Quote

>Also, are Halt and Exit procedures considered one of the deadly sins?

No, they are the preferable ways to do things. Also with TP 7.0 use
break and continue.

Osmo

Re:Couple of questions.


On 14 Jul 1998 01:54:05 GMT, "Joe Mumbauer" <Mu...@Erols.COM> wrote:

Quote
>First, is there a speed difference between these two code segments:

>WHILE (Counter > 1) AND NOT(Flag) DO
>    BEGIN
>            Counter := Counter - 1;
>            Flag := StrVar[Counter] = 'a'
>    END;

>            or

>WHILE (Counter > 1) AND (StrVar[Counter] <> 'a') DO
>    Counter := Counter - 1;

The second is probably a bit faster.
In the first piece of code, the value of

        StrVar[Counter] = 'a'

is assigned to the variable Flag.
In the loop condition, the value of flag is evaluated.

In the second code segment, the assignment to Flag and the evaluation
of Flag don't take place.

A really smart optimising compiler might see that the loops are the
same, and replace the first solution by the second one, though, but BP
doesn't do this (Just check it with TD, and you'll see the
difference).

Quote
>Also, are Halt and Exit procedures considered one of the deadly sins?
>Thanks for all help,

No. I use them wherever they come in handy, and I still live.
Writing unreadable code that is supposed to be maintained by someone
else _is_.

Quote
>Joe Mumbauer.  Mu...@Erols.COM

Klaas.

Re:Couple of questions.


Quote
Joe Mumbauer wrote:
> First, is there a speed difference between these two code segments:

> WHILE (Counter > 1) AND NOT(Flag) DO
>         BEGIN
>                 Counter := Counter - 1;
>                 Flag := StrVar[Counter] = 'a'
>         END;

>                 or

> WHILE (Counter > 1) AND (StrVar[Counter] <> 'a') DO
>         Counter := Counter - 1;

     To answer the question "which is faster", do a test.  However,
more interesting (IMHO) is that these routines (as they stand)
represent different programs.  Note that the first routine decrements
counter, then tests, while the second tests, then decrements.  Unless
Flag is initialized to StrVar[Counter] = 'a', the first fragment will
miss
those strings ending in 'a'.

Bob Schor
Pascal Enthusiast

P.S. -- my preference is for the second version, regardless of speed.
My personal preference is to choose the code that is easier for a human
to understand (particularly myself, six months after I wrote the thing).

The second version, I think, fulfills this "rule" much better.

Re:Couple of questions.


In article: <01bdaeca$0d89bf80$3aa1a...@Mumbs.Erols>  "Joe Mumbauer"

Quote
<Mu...@Erols.COM> writes:

[...]

Quote
>Also, are Halt and Exit procedures considered one of the deadly sins?
>Thanks for all help,

Not by me they're not. Purists might call them that, but purists never write any
real-world code. A good guidline is that it is permissible to jump OUT of code,
but never INTO it (though there are exceptions to every rule). It's impossible
to jump INTO a code segment with Halt, Exit, Break or Continue, so they're ok -
when used for the right reasons.

-- Jay

 -----------------------------------------
| Jason Burgon - author of Graphic Vision |
| g...@jayman.demon.co.uk                   |
| http://www.jayman.demon.co.uk           |
 -----------------------------------------

Re:Couple of questions.


Quote
Frank Peelo wrote:
> Hans J?rg Brinksmeyer wrote in message
> <35ABD839.2F67F...@physik.uni-marburg.de>...
> >Frank Peelo wrote:
> >> If you initialise Flag to StrVar[Counter] = 'a' the loops will
> >> function identically but the second version is more elegant,
> compiles
> >> to less code and will be easier to maintain (if you want to search
> for
> >> 'b' instead, you only have to change one line instead of two).

> >That is not right at all. In the last case, both loops will be
> entered the
> >same often in the last case, but they do not take the same time. The
> >runtime ratio of these two loops is about 2 to 3 in favour of the
> second
> >one. So, the second is not only more elegant but also faster.

> >I ghink this really hits the question, doesn't it?

> Well, I didn't comment on speed but apart from that you seem to be
> agreeing with me. I said the second version is better [more elegant,
> smaller object code], you say that's wrong, the second version is
> better. Am I missing something here?

> There is a subtle difference in behaviour between the two code
> fragments, depending on how Flag is initialised. ISTM that at most one
> of the behaviours can be correct. "The speed of a nonworking program
> is irrelevant", so I would have thought the question was about how to
> determine which fragment worked right.

> FP

My intention was not to say you're wrong, sorry.

The way I understood the initial question was more technical, if there are
any differences in runtime when both loops are run only once.

I'd like to stress that, if the starting conditions (initialization of
FLAG) are used as you described them in the last case, there are runtime
differences between both procedures.

I hope it's clear to everyone that a code segment or loop that is not
entered doesn't produce any recognizable runtime. So, if you want to
compare the two segments with regard to their runtime properties, you must
take care of same starting conditions.

Best regards

Hans J?rg Brinksmeyer

Other Threads