[fpc-pascal] for .. in loop implementation

Vinzent Höfler JeLlyFish.software at gmx.net
Wed Jan 7 19:57:40 CET 2009

Jürgen Hestermann wrote:
>> I disagree with any statement saying that for .. in loop is
>> only a type-saver. It's a good language extension and should be included
>> (since Delphi already have this, it will also be a good idea). 
>> Consider the
>> following example:
>>   for d in [Monday,Wednesday,Friday] do ;
>>   // versus
>>   for d:=Low(TDaySet) to High(TDaySet) do
>>     if d in [Monday,Wednesday,Friday] then ;
>> The latter one has iteration overheads, while the former can be 
>> optimized to
>> loop as many as needed. I'm not saying I'm the best Pascal programmer, 
>> but
>> in case there's a (better) solution to this (rather than extending the
>> language) please tell me.
> I think there will be no performance difference because internaly the 
> compiler has to generate something like the first for-loop anyway.

No. It could unroll the loop, and then use constants throughout the 
three copied loop-bodies instead. Of course, a smart compiler could end 
up with the same approach after analyzing the code, so indeed: There 
should be no performance difference.

> It 
> will only be hidden from the programmer and I am not sure whether this a 
> good thing.
> Everything that obscures what's going on under the hood has the 
> potential to generate performance problems.

Yes, that's what I hear from C-enthusiasts all the time. And that's also 
why everything should be written in assembler these days, because then 
performance problems would jump right at you when reading the code.

(In case anyone wonders, yes, the last sentence above is 100% sarcasm.)

 > In your example, you may not
> be aware that at the end all possible members have to be checked for 
> beeing part of the set. If you only read
> for d in [Monday,Wednesday,Friday] do ;
> you may think that the loop is run through only 3 times, but internally 
> there are much more iterations (to check the "if d in 
> [Monday,Wednesday,Friday]").

Indeed. But there could even be no loop at all, even if there's a loop 
expression in the source code.


P.S. Honestly, Pascal (and especially ObjectPascal) already hides quite 
some stuff from the programmer. Properties, for example, can hide 
potentially costly procedure calls in simple assignment statements.

Things like

SomeStringList['Name'] := 'Value';

might be a relatively cheap O(1) operation if implemented with a hash 
table, it could be an O(log n) operation if the list is sorted and a 
binary search is done, or it could even be a O(n) operation if 
implemented by a simple linear search, but who knows? Some of the time 
you don't even care, because the number of strings is not large enough 
to make a noticeably difference; in fact, the usage of AnsiStrings alone 
and the associated reference counting and constant memory allocation and 
deallocation might even be much more influencing on the overall performance.

Don't get me wrong, usually this hiding of implementation details is a 
good thing, because it let's you solve the problem at hand a lot more 
quicker. If the solution turns out to be "not fast enough", you can 
still start optimizing instead of doing it the other way around.

Mantra: First make it work, then make it fast.

IOW: A fast, but wrong solution is one thing first: Wrong. No matter how 
fast it does it wrong.

BTW, any performance differences in the example above highly depends on 
the work done in the loop body anyway, so whining about possible 
performance issues is quite a bit premature here. ;)

More information about the fpc-pascal mailing list