Hi,

I'm busy working on some of the remaining unit tests for the tiOPF
project that doesn't run 100% to my satisfaction yet under FPC
(compared to Delphi 7). One of the tests is for a Simple Encryption
algorithm implemented in tiOPF, that runs extremely slow under FPC
2.4.x (and 2.6.0-rc), and near instant under Delphi 7. I'm trying to
figure out why.

Below is a snippet of code I tracked down which contains the slowdown.
The problem under FPC lies with line 08, and more specifically the
call to Random(255). Simply replacing the Random(255) call with a
variable speeds up the loop by some 529 times!

I did a simple GetTickCount() timing around this loop. Delphi executes
the loop in 20 ticks. FPC 2.6.0-rc2 takes 10585 ticks!!!! The outer
loop runs 200400 iterations. The types for BitValue, ByteValue and
RandSeed is of type Byte.

01  for Index := 1 to Length(Source) do
02  begin
03    OrdValue := Ord(Source[Index]);
04    for BitCount := 0 to 7 do
05    begin
06      BitValue := Byte(OrdValue and (1 shl BitCount) = 1 shl BitCount);
07      RandSeed := ByteValue;
08      ByteValue := (((Random(255) + 1) div 2) * 2) + BitValue;
09      Result[(Index - 1) * 8 + BitCount + 1] := AnsiChar(ByteValue);
10    end;
11  end;

I'm using 64bit Ubuntu Linux 10.04.3 with 64-bit FPC 2.6.0-rc2.
Anybody have any ideas why the code under FPC runs so slowly? Is it
maybe some type conversion problem in FPC? I noticed that Random()
returns a Int64 on my Linux system. I'm not sure what it returns under
Delphi 7 (the docs don't say, and I can see the implementation of it).


If you wanted to test this, I attached a fully working program code
(snippets from the original tiOPF code) to demonstrate the problem.


-- 
Regards,
  - Graeme -


_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://fpgui.sourceforge.net
program speedtest;

{$IFDEF FPC}
  {$mode delphi}{$H+}
{$ELSE}
  {$APPTYPE Console}
{$ENDIF}

uses
  Classes, SysUtils;

function GetTickCount: Cardinal;
begin
  Result := Cardinal(Trunc(Now * 24 * 60 * 60 * 1000));
end;


function GetTestString: string;
var
  i     : integer;
  lsLine : string;
begin
  SetLength(lsLine, 1000);
  for i := 1 to 1000 do
    lsLine[ i ]:= Chr(ord('A')+random(ord('z')-ord('A')));
  for i := 1 to 200 do
    result := result + lsLine + #13 + #10;
  result := result + 'x'; // make it an odd number
end;

function EncryptString(const psData : AnsiString): AnsiString;
var
  OrdValue: Byte;
  Index: Integer;
  BitCount: Integer;
  BitValue: Byte;
  ByteValue: Byte;
  Source: ansiString;
  c: Cardinal;
begin
  writeln('Length(psData) = ', Length(psData));
  ByteValue := Random(255) + 1;
  writeln('ByteValue: ', ByteValue);
  Source := psData;
  writeln('Length(Source) = ', Length(Source));
  SetLength(Result, Length(Source) * 8);
  writeln('First Loop....');
  c := GetTickCount;
  for Index := 1 to Length(Source) do
  begin
    OrdValue := Ord(Source[Index]);
    for BitCount := 0 to 7 do
    begin
      BitValue := Byte(OrdValue and (1 shl BitCount) = 1 shl BitCount);
      RandSeed := ByteValue;
      ByteValue := (((Random(255) + 1) div 2) * 2) + BitValue;
      { Replace the above line with the following to see the speed difference }
//      ByteValue := (((ByteValue + 1) div 2) * 2) + BitValue;
      Result[(Index - 1) * 8 + BitCount + 1] := AnsiChar(ByteValue);
    end;
  end;
  writeln('elapsed time: ', GetTickCount - c);
end;

var
  s: string;
begin
  Randomize;
  s := GetTestString;
  s := EncryptString(s);
end.
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to