[fpc-devel] Const optimization is a serious bug

Max Vlasov max.vlasov at gmail.com
Sat Jul 9 01:09:46 CEST 2011


On Fri, Jul 8, 2011 at 2:05 PM, Jonas Maebe <jonas.maebe at elis.ugent.be> wrote:
> The main proposals I've seen were
> a) treat const string parameters the same as value parameters (i.e., get rid
> of the current const behaviour)
> b) the same as a), combined with a very conservative heuristic to apply the
> optimization in case there can be no side effects. I.e., in case there is
> not a single function call and not a single indirect write (var parameter,
> pointer, global variable, dynamic array, ...) to any string or anything that
> might be somehow aliased to a string passed as parameter to the current
> routine
> c) keep the current behaviour, but add functionality to the compiler to help
> debug problems that can occur as a result of problems that can occur as a
> result of this behaviour
>


It's a very interesting topic indeed and it's pleasure to read all
those comments regardless of the actual consequences :)

Actually when I first reply to the OP, I didn't go deeply in the
technical side, but when I finally understood what was going on, a
thought (you can call it d to your a,b,c) came. I'm not familiar with
all the aspects of the compiler and ansistrings implementation, so my
observations can be wrong. So sorry in advance :-)

The answer is indirect referencing. it's a workaround that probably
will solve the problem, but I must admit that I don't know what is the
exact performance price. The compiler when it detects const s:
ansistring could switch to passing not the actual address of the
string, but the address of the variable that holds it. In other words
passing PString instead of string. In this case no reference counting
or exception frame is probably created and at the same time, if the
used string is reallocated occasionally because of a side change, the
code will not fail because it will just automatically use the new
modified address.

Sure I can not implement the exact patch right now but loosely it can
be replace with the following approach. It's a simulation with using
PString instead of const string. Here are two procedure that I tried
to measure

function CRCConstString(const Str: string): integer;
var
  i: integer;
begin
  Result:=0;
  for i:=1 to Length(Str) do
    Result:=Result + Ord(Str[i]);
end;

... measuring
  for i:=0 to 100000 do
    CRCConstString(FString);

...and

function CRCPString(Str: PString): integer;
var
  i: integer;
begin
  Result:=0;
  for i:=1 to Length(Str^) do
    Result:=Result + Ord(Str^[i]);
  end;
end;

.... measuring
  for i:=0 to 100000 do
   CRCPString(@FString);


The bad news is that measuring the difference between two fully
optimized version (Windows) gave 20% difference, so PString variant is
slower. But I keep being optimistic because:
- Delphi 5 showed no significant difference at all
- if the compiler is doing this, it can do better than me anyway.

Also, I modified the Chad's original example to simulate this apporach
and it seems it helped.

Max



More information about the fpc-devel mailing list