[fpc-pascal]Performance: Free Pascal vs GNU Pascal

Michael.VanCanneyt at Wisa.be Michael.VanCanneyt at Wisa.be
Sun Dec 29 10:44:05 CET 2002


On Sat, 28 Dec 2002, Mark Emerson wrote:

> How fast is the code generated by FPC versus GPC?  Have there been any
> benchmarks comparing FPC with GPC....especially on Windows...in other
> words how well are these compilers optimizing?
>
> I haven't written Pascal code in years...but the Borland compilers made
> code that "screamed"....on those old platforms.  While I realize a
> comparison might not be possible, how does FPC (and GPC) compare to the
> old Borland style compilers?

Look at
http://dada.perl.it/shootout/

>
> Also, does anyone have a feeling of how the current Pascal optimizations
> compare to the C compiler optimizations for various platforms?  In other
> words, is there any merit to the claim I'ver heard that the fastest
> compiled code comes from C compilers?

Such statements are generally unusable and not verifiable. There exist some
benchmarks, but the quality of the algorithms is usually not very good; a C
programmer will not produce optimal pascal algorithms and vice versa.
You will see this if you look at some of the source files on the above site.

For example, the array access function test from the above site:

uses SysUtils, Classes;

var
    n, i, k, last : longint;
    X, Y : TList;
begin
    if ParamCount = 0 then
      n := 1
    else
       n := StrToInt(ParamStr(1));
    if n < 1 then n := 1;
    last := n - 1;
    X := TList.Create;
    X.Capacity := n;
    For i := 0 To last do
        X.Add( Pointer(i+1) );
    Y := TList.Create;
    Y.Capacity := n;
    For i := 0 To last do
        Y.Add( Pointer(0) );
    For k := 0 To 999 do
    begin
        For i := last downto 0 do
        begin
            Y.Items[i] := Pointer(longint(Y.Items[i]) +longint(X.Items[i]));
        end;
    end;
    Writeln (IntToStr(longint(Y.Items[0])), ' ', IntToStr(longint(Y.Items[last])));
end.

As you can see, a TList is used; which is VERY slow.

And the C version:

#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[]) {
    int n = ((argc == 2) ? atoi(argv[1]) : 1);
    int i, k, *x, *y;

    x = (int *) calloc(n, sizeof(int));
    y = (int *) calloc(n, sizeof(int));

    for (i = 0; i < n; i++) {
    x[i] = i + 1;
    }
    for (k=0; k<1000; k++) {
    for (i = n-1; i >= 0; i--) {
        y[i] += x[i];
    }
    }

    fprintf(stdout, "%d %d\n", y[0], y[n-1]);

    free(x);
    free(y);

    return(0);
}

Obviously, these algorithms are not comparable at all.

A more 'correct' pascal algorithm would be

uses sysutils;

var
    n, i, k, last : longint;
    X, Y : PLongint;

begin
    if ParamCount = 0 then
      n := 1
    else
       n := StrToInt(ParamStr(1));
    if n < 1 then n := 1;
    last := n - 1;
    GetMem(X,N*SizeOf(Longint));
    GetMem(Y,N*SizeOf(Longint));
    For i := 0 To last do
      X[i]:=I+1;
    For k := 0 To 999 do
      For i:=last downto 0 do
        Y[i]:=Y[i]+X[i];
    Writeln (Y[0], ' ',Y[last]);
    FreeMem(X);
    FreeMem(Y);
end.

This code is about 3 times faster than the first algorithm.

If you need some really really fast code, you could even include assembler in your
code in critical parts.

Just to say that comparison is difficult.

Michael.





More information about the fpc-pascal mailing list