From: bart.c on

"Keith Thompson" <kst-u(a)mib.org> wrote in message
news:lnr5lza0tb.fsf(a)nuthaus.mib.org...
> Seebs <usenet-nospam(a)seebs.net> writes:
>> On 2010-04-28, bart.c <bartc(a)freeuk.com> wrote:
>>> int* findvalue(int value)
>>> {int *a=0;
>>> for(int xInd = 0; !a && xInd < datasize; ++xInd)
>>> for(int yInd = 0; !a && yInd < dataxindsize; ++yInd)
>>> for(int zInd = 0; !a && zInd < dataxindyindsize; ++zInd)
>>> {
>>> if(data[xInd][yInd][zInd] == value)
>>> a=&data[xInd][yInd][zInd];
>>> }
>>> return a;
>>> }
>>
>> This is noticably slower and less clear. I would not consider it
>> an acceptable rewrite -- but I would consider the other form a good
>> rewrite of it.

> I mostly agree, but -- "noticably slower"? How did you notice?

I thought the issue was clarity rather than performance. But as it happened
I did measure my code with a version using the return in the inner loop, and
the latter was faster (at least, with a 2x3x4 array of ints).

> I also wonder why Bartc changed the index type from size_t to int.

I don't like size_t's (because they look unwieldy). And if speed is a
factor, I don't see the point of allowing the compiler to use 64-bit indices
when 32-bit ones might do just as well, and possibly better.

> For the body of the inner loop, I might consider writing:
>
> const int *p = &data[xInd][yInd][zInd];
> if (*p == value) {
> return p;
> }
>
> For a sufficiently naive compiler, it might avoid recomputing
> the address; that by itself probably isn't a good enough reason
> to do it, since I suspect most decent optimizing compilers will
> avoid recomputing it anyway. But it also avoids writing a fairly
> complex expression twice, which could be helpful to the reader.

The second expression is only evaluated once (compared with
possibly millions of times for the first).

> A typo in one of the two occurrences of data[xInd][yInd][zInd]
> could result in a bug that's very difficult to track down.

When clarity is important, using xInd, yInd, zInd instead of just x,y,z,
size_t instead of int (and declaring those inside instead of outside the
loops), and those long expressions for the bounds of each dimension, have a
bigger impact, imo, than adding an extra test.

--
Bartc

From: Willem on
Richard Heathfield wrote:
) In any case, your loop condition expressions do not correctly describe
) the conditions under which the loop will terminate. Please rewrite your
) example so that they do, and then by all means ask me again if you wish.

Don't be silly.

'loop conditions should correctly describe the conditions under
which the loop will terminate' is a requirement that is roughly
equivalent to 'you should never exit from within a loop'.

In other words, you're begging the question.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
From: Keith Thompson on
Jeff Flinn <TriumphSprint2000(a)hotmail.com> writes:
> Keith Thompson wrote:
>> Seebs <usenet-nospam(a)seebs.net> writes:
>>> On 2010-04-28, bart.c <bartc(a)freeuk.com> wrote:
>>>> int* findvalue(int value)
>>>> {int *a=0;
>>>>
>>>> for(int xInd = 0; !a && xInd < datasize; ++xInd)
>>>> for(int yInd = 0; !a && yInd < dataxindsize; ++yInd)
>>>> for(int zInd = 0; !a && zInd < dataxindyindsize; ++zInd)
>>>> {
>>>> if(data[xInd][yInd][zInd] == value)
>>>> a=&data[xInd][yInd][zInd];
>>>> }
>>>>
>>>> return a;
>>>> }
>>> This is noticably slower and less clear. I would not consider it
>>> an acceptable rewrite -- but I would consider the other form a good
>>> rewrite of it.
>>
>> I mostly agree, but -- "noticably slower"? How did you notice?
>
> Certainly is for the case data[0][0][0] == value. ;-)

How so?

I'm not arguing that it's not *likely* to be slower, but (a) it's not
likely to be *noticeably* slower unless the entire loop is executed many
many times, and (b) it might not be slower at all, depending on how
clever the compiler is.

(I'm assuming there's not some semantic difference that I haven't
noticed.)

--
Keith Thompson (The_Other_Keith) kst-u(a)mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
From: Phil Carmody on
"Daniel T." <daniel_t(a)earthlink.net> writes:
> Phil Carmody <thefatphil_demunged(a)yahoo.co.uk> wrote:
>> "Daniel T." <daniel_t(a)earthlink.net> writes:
>>
>> > The debate is not the false dichotomy that some try to make it out
>> > to be.
>>
>> It's odd that you appear to have attempted to push it towards a
>> dichotomy with the above.
>
> Not at all. I specifically picked strychnine because it is something
> that can be taken (but it's far from common.) I am simply pointing out
> that there are degrees, and the debate is about degrees, not about
> throwing a switch.
>
> Three examples have been presented using your analogy, water, salt, and
> strychnine. The question is, which is goto more like? The question isn't
> "whether" goto is safe to use, but "how safe is it." Are better
> alternatives available?

IMHO, if you're deep in the linux kernel or its drivers, then it's
salt. You really don't want much, but some is almost always necessary,
and then it's definitely better than the lack thereof.

If you're in some bloaty multi-layered, multi-libraried userspace
program, then it's strychnine. If you're pretending to obsess about
the extra efficiency goto gives you, you're missing the point.

If it's water, and you're awash with gotos, then you're in the wrong
language.

Phil
--
I find the easiest thing to do is to k/f myself and just troll away
-- David Melville on r.a.s.f1
From: Keith Thompson on
"bart.c" <bartc(a)freeuk.com> writes:
> "Keith Thompson" <kst-u(a)mib.org> wrote in message
> news:lnr5lza0tb.fsf(a)nuthaus.mib.org...
>> Seebs <usenet-nospam(a)seebs.net> writes:
>>> On 2010-04-28, bart.c <bartc(a)freeuk.com> wrote:
>>>> int* findvalue(int value)
>>>> {int *a=0;
>>>> for(int xInd = 0; !a && xInd < datasize; ++xInd)
>>>> for(int yInd = 0; !a && yInd < dataxindsize; ++yInd)
>>>> for(int zInd = 0; !a && zInd < dataxindyindsize; ++zInd)
>>>> {
>>>> if(data[xInd][yInd][zInd] == value)
>>>> a=&data[xInd][yInd][zInd];
>>>> }
>>>> return a;
>>>> }
>>>
>>> This is noticably slower and less clear. I would not consider it
>>> an acceptable rewrite -- but I would consider the other form a good
>>> rewrite of it.
>
>> I mostly agree, but -- "noticably slower"? How did you notice?
>
> I thought the issue was clarity rather than performance. But as it happened
> I did measure my code with a version using the return in the inner loop, and
> the latter was faster (at least, with a 2x3x4 array of ints).

Actual measurement? Now you've spoiled everybody's empty speculation!

>> I also wonder why Bartc changed the index type from size_t to int.
>
> I don't like size_t's (because they look unwieldy). And if speed is a
> factor, I don't see the point of allowing the compiler to use 64-bit indices
> when 32-bit ones might do just as well, and possibly better.

Speaking of "clarity rather than performance" ...

32-bit (or even 16-bit if int is that small) indices might *not* be
sufficient, and if they're not then you're probably not going to get a
warning from the compiler. size_t is (almost?) guaranteed to be big
enough. And it's not clear 32-bit indices are going to give you faster
code than 64-bit indices.

>> For the body of the inner loop, I might consider writing:
>>
>> const int *p = &data[xInd][yInd][zInd];
>> if (*p == value) {
>> return p;
>> }
>>
>> For a sufficiently naive compiler, it might avoid recomputing
>> the address; that by itself probably isn't a good enough reason
>> to do it, since I suspect most decent optimizing compilers will
>> avoid recomputing it anyway. But it also avoids writing a fairly
>> complex expression twice, which could be helpful to the reader.
>
> The second expression is only evaluated once (compared with
> possibly millions of times for the first).

Ah, good point!

>> A typo in one of the two occurrences of data[xInd][yInd][zInd]
>> could result in a bug that's very difficult to track down.
>
> When clarity is important, using xInd, yInd, zInd instead of just x,y,z,
> size_t instead of int (and declaring those inside instead of outside the
> loops), and those long expressions for the bounds of each dimension, have a
> bigger impact, imo, than adding an extra test.

I agree about xInd, yInd, and zInd. I disagree about size_t. And I
find declaring the indices inside the loops to be substantially
clearer than declaring them separately (assuming your compiler
supports that feature, of course).

--
Keith Thompson (The_Other_Keith) kst-u(a)mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"