Bench2

Version 11 - October 17th, 2006
Made by Laurent Duveau
  web Site : http://www.aldweb.com/
  e-mail : info@aldweb.com


BENCH2 SOURCE CODES FOR ALL SINGLE DEVELOPMENT TOOLS

If you would like to help me extend this list of already benchmarked development tools and are working on one which is not listed here yet (especially ARM benchmark in CodeWarrior and GCC, newer versions of the different development tools), I would be more than happy if you get in touch with me.

I would like to address here a very special THANK YOU to those who already helped me so far:
- Fred Bayer (author of LispMe)
- Jeremy Dewey (from OrbWorks, Inc., editor of PocketC, OrbForms Designer and PocketC Architect)
- Peter Dickerson
- Arnaud Farine
- Marc Furrer
- Ingbert Grimpe
- Philippe Guillot (author of PP)
- George Henne (from NSBasic, Corp., editor of NS Basic/Palm)
- Christopher Hill
- Pascal Levy and Jean-Philippe Amaré (from Peter Holmes Consulting, Inc., editor of HB++)
- Kawa
- David Mekersa
- Adrian Nicolaiev
- Frank O'Brien (from CASLsoft, editor of CASL)
- Ben Ong
- Philippe Rossi



Legend:

68k Source Code
ARM Source Code


AppForge v5.1.1 - http://www.appforge.com/

Option Explicit

Private b As Integer
Private WithEvents cs As CSystem

Private Sub btnGo_Click()
   Me.AFLabel2.Caption = vbNullString
   Me.AFLabel4.Caption = vbNullString
   b = 1
   Me.AFLabel2.Caption = CStr(PerfectNum)
   b = 2
   Me.AFLabel4.Caption = CStr(PerfectNum)
End Sub

Private Function PerfectNum() As Double
   Dim n As Long
   Dim d As Long
   Dim m As Long
   Dim s As Long
   Dim p As Long
   Dim t As Long
   Dim r As Double

   t = afSystem.TimerMS
   p = 0
   For n = 2 To b * 500
     m = n / 2
     s = 1
     For d = 2 To m
       If b = 1 Then
         If CSng(n) / CSng(d) = (n \ d) Then s = s + d
       End If
       If b = 2 Then
         If (n Mod d) = 0 Then s = s + d
       End If
     Next d
     If s = n Then p = p + 1
   Next n
   r = CDbl(afSystem.TimerMS - t) / 1000
   If p <> 3 Then r = 0
   PerfectNum = r
End Function

Private Sub cs_AppBackground()
   End
End Sub

Private Sub cs_AppMinimized()
   End
End Sub

Private Sub Form_Load()
   Set cs = New CSystem
End Sub
Note : Thanks to Ingbert Grimpe for providing me with the AppForge source code and executable.


CASL and CASLpro v4.1.3 - http://www.caslsoft.com/

variables;
  numeric nT[2];
end;

function PerfectNum(numeric nB);
  variables;
    # would be faster if all declared as integers, but CASL supports
    #  only double floating numbers, CASL will support integers in Q4 of 2004
    numeric nP; # num of perfect numbers
    numeric nN; # numerator, candidate perfect number
    numeric nM; # half of candidate perfect number
    numeric nD; # divisor
    numeric nS; # sum of integer quotients
  end;
  nT[nB-1]=timevalue; # start timer
  nP=0;
  for nN=2, nN<=nB*500;
    nM = int(nN/2);
    nS = 1;
    for nD=2, nD<=nM;
      if nB=1;
        if (nN/nD)=int(nN/nD);
          nS = nS+nD;
        end_if;
      else_if nB=2;
        if (nN % nD)=0;
          nS = nS+nD;
        end_if;
      end_if;
    next nD;
    if nS=nN;
      nP = nP+1;
    end_if;
  next nN;
  nT[nB-1]=timevalue-nT[nB-1]; # end timer
  if nP<>3;
    nT[nB-1] = 0;
  end_if;
  # display elasped time and total of both passes
  lbTime[nB-1].display="Elasped time "+string(nB,"")+" = "+string(nT[nB-1]/1000,"#.###")+" s";
  lbTime[2].display="Elasped time 1+2 = "+string((nT[0]+nT[1])/1000,"#.###")+" s";
end;

# called by Start button, main function
function btStart;
  variables;
    numeric nB; # counter
  end;
  # clear out any prior data and display
  nT[0]=0;
  nT[1]=0;
  lbTime[0].display="...";
  lbTime[1].display="Counting perfect numbers...";
  lbTime[2].display="...";
  # call the perfect number counter twice, and display elasped time each time and total
  for nB=1,nB<=2;
    PerfectNum(nB);
  next nB;
end;
Note : Thanks to Frank O'Brien for providing me with the CASL source code and executable.


cbasPad v0.97b4 - http://www.nicholson.com/rhn/pilot.html

# Bench2
new
10 for B%=1 to 2
20 gosub 50
30 next B%
40 end
# Perfect Numbers finder routine
50 T%=fn 17
60 P%=0
70 C%=B%*500
80 for N%=2 to C%
90 M%=N%/2
100 S%=1
110 for D%=2 to M%
120 if B%=1 then if (N%/D%)=int(N%/D%) then S%=S%+D%
130 if B%=2 then if (N% mod D%)=0 then S%=S%+D%
140 next D%
150 if S%=N% then P%=P%+1
160 next N%
170 R=(fn 17 - T%)/100
180 if P%<>3 then R=0
190 dprint str$(R)+" Secs"
200 return
run
Note : Line 70 is needed because writing directly [ 80 for N%=2 to B%*500 ] produces a Type error!


cbasPad v5.3b0i - http://www.nicholson.com/rhn/pilot.html

# Bench2Arm cbasPad
new
10 dim B as integer
20 dim D as integer
30 dim N as integer
40 dim M as integer
50 dim P as integer
60 dim S as integer
70 dim T as integer
80 for B=1 to 2
90 gosub 120
100 next B
110 end
# Perfect Numbers finder routine
120 T=fn timer(100)
130 P=0
140 for N=2 to B*500
150 M=N/2
160 S=1
170 for D=2 to M
180 if B=1 then if (N/D)=int(N/D) then S=S+D
190 if B=2 then if (N mod D)=0 then S=S+D
200 next D
210 if S=N then P=P+1
220 next N
230 R=(fn timer(100) - T)/100
240 if P<>3 then R=0
250 dprint str$(R)+" Secs"
260 return
run


CodeWarrior v8.0 - http://www.codewarrior.com/

int b;

void PerfectNum() {
// Perfect Numbers finder routine
  int n,d,m,s,p;
  long t;
  float r;
  char c[80],v[80];

  t=TimGetTicks();
  p=0;
  for(n=2;n<=b*500;n++) {
    m=n/2;
    s=1;
    for(d=2;d<=m;d++) {
      if(b==1) if((((float)n)/((float)d))==(n/d)) s=s+d;
      if(b==2) if((n%d)==0) s=s+d;
    }
    if(s==n) p=p+1;
  }
  r=((float)(TimGetTicks()-t))/((float)SysTicksPerSecond());
  if(p!=3) r=0;
  StrIToA(c,(int)r);
  StrCat(c,".");
  r=(r-(int)r)*100;
  StrIToA(v,(int)r);
  StrCat(c,v);
  StrCat(c," Secs");
  WinDrawChars(c,StrLen(c),1,10*b);
  return;
}

static int StartApplication(void) {
  for(b=1;b<=2;b++) {
    PerfectNum();
  }
  SysTaskDelay(5*SysTicksPerSecond());
  return 0;
}
Note : Thanks to David Mekersa for providing me with the CodeWarrior source code and executable.


Falch.net v2.5 (PRCTools v2.0) - http://www.falch.net/

int b;

void PerfectNum() {
// Perfect Numbers finder routine
  int n,d,m,s,p;
  long t;
  float r;
  char c[80],v[80];

  t=TimGetTicks();
  p=0;
  for(n=2;n<=b*500;n++) {
    m=n/2;
    s=1;
    for(d=2;d<=m;d++) {
      if(b==1) if((((float)n)/((float)d))==(n/d)) s=s+d;
      if(b==2) if((n%d)==0) s=s+d;
    }
    if(s==n) p=p+1;
  }
  r=((float)(TimGetTicks()-t))/((float)SysTicksPerSecond());
  if(p!=3) r=0;
  StrIToA(c,(int)r);
  StrCat(c,".");
  r=(r-(int)r)*100;
  StrIToA(v,(int)r);
  StrCat(c,v);
  StrCat(c," Secs");
  WinDrawChars(c,StrLen(c),1,10*b);
  return;
}

static int StartApplication(void) {
  for(b=1;b<=2;b++) {
    PerfectNum();
  }
  SysTaskDelay(5*SysTicksPerSecond());
  return 0;
}
Note : Thanks to Philippe Rossi for providing me with the Falch.net source code and executable.


HB++ v1.02 - http://www.handheld-basic.com/

Public b as Integer

Public Function PerfectNum() as Double
  dim n as Integer
  dim d as Integer
  dim m as Integer
  dim s as Integer
  dim p as Integer
  dim t as long
  dim r as Double

  t=ticks
  p=0
  for n=2 to b*500
    m=n/2
    s=1
    for d=2 to m
      if b=1 then
        if (csng(n)/csng(d))=(n/d) then s=s+d
      end if
      if b=2 then
        if (n mod d)=0 then s=s+d
      end if
    next d
    if s=n then p=p+1
  next n
  r=cdbl(ticks-t)/tickspersecond
  if p<>3 then r=0
  PerfectNum=r
End Function

Private Sub cmdGo_Click()
  cmdGo.Text="Wait..."
  Field1.Text=""
  Field2.Text=""
  b=1
  Field1.Text=Format(PerfectNum,"#.00")
  b=2
  Field2.Text=Format(PerfectNum,"#.00")
  cmdGo.Text="Go !"
End Sub

Private Sub Application_NormalLaunch()
  dim f as new frmMain
  f.Show hbFormModeless+hbFormGoto
End Sub
Note 1 : Thanks to Pascal Levy for providing me with the HB++ source code and executable.
Note 2 : Thanks to Jean-Philippe Amaré for providing me with a full version of HB++ for the purpose of this Bench2 analysis.


HotPaw Basic v1.4.1 - http://www.hotpaw.com/rhn/hotpaw/

# Bench2.bas
dim b as integer
draw -1
print at 1,20
for b=1 to 2
  gosub PerfectNum
next b
k$=input$(1)
end

sub PerfectNum
' Perfect Numbers finder routine
  dim n,d,m,s,p,t as integer
  t=timer(100)
  p=0
  for n=2 to b*500
    m=n/2
    s=1
    for d=2 to m
       if b=1 then if (n/d)=int(n/d) then s=s+d
       if b=2 then if (n mod d)=0 then s=s+d
    next d
    if s=n then p=p+1
  next n
  r=(timer(100)-t)/100
  if p<>3 then r=0
  print r;" Secs"
end sub


HSPascal v2.1.0 - http://hspascal.fihl.net/

Program Bench2;

{$ApplName Bench2,BEN2}

Uses
  TimeMgr,SystemMgr,Crt,HSUtils;

Var
  B: integer;

procedure PerfectNum;
{ Perfect Numbers finder routine }
  var
    N,D,M,S,P: integer;
    T: longint;
    R: real;
    C: string;
  begin
    T:=TimGetTicks;
    P:=0;
    for N:=2 to B*500 do begin
      M:=N div 2;
      S:=1;
      for D:=2 to M do begin
        if B=1 then if (N/D)=(N div D) then S:=S+D;
        if B=2 then if (N mod D)=0 then S:=S+D;
      end;
      if S=N then P:=P+1;
    end;
    R:=(TimGetTicks-T)/SysTicksPerSecond;
    if P<>3 then R:=0;
    str(R:5:2,C);
    writeln(C+' Secs');
  end;

begin
  for B:=1 to 2 do
    PerfectNum;
  Delay(5000);
end.


iziBasic v1.0 - http://www.aldweb.com/ (yeah, that's my work!)

' Bench2.ibas
{CREATORID "LDB2"}
{VERSION "1.0"}

BEGIN
FOR B=1 TO 2
   GOSUB PerfectNum
NEXT
WAIT
END

PerfectNum:
   T=TICKS
   P=0 : C=B*500
   FOR N=2 TO C
      M=N\2 : S=1
      FOR D=2 TO M
         IF B=1 LET Y=N/D : X=N\D : IF Y=X LET S=S+D
         IF B=2 LET Y=N MOD D : IF Y=0 LET S=S+D
      NEXT
      IF S=N LET P=P+1
   NEXT
   R=TICKS-T/TICKSPERSEC
   IF P<>3 LET R=0
   PRINT R USING 2;
   PRINT " Secs"
RETURN


Jump2 v2.0ß8 - http://sourceforge.net/projects/jump/

import waba.ui.*;
import waba.fx.*;
import waba.sys.*;
public class BenchJump2 extends MainWindow {

  public void onStart() {
    for(int b=1;b<=2;b++) {
      benchmark(b);
    }
  }

  private void benchmark(int b) {
    int t = Vm.getTimeStamp();
    int p = 0;
    for (int n=2;n<=b*500;n++) {
      int m = n/2;
      int s = 1;
      for (int d=2;d<=m;d++) {
        if (b==1) if (((float)n)/((float)d) == n/d) s=s+d;
        if (b==2) if (n%d == 0) s=s+d;
      }
      if (s==n) p=p+1;
    }
    float r = ((float)(Vm.getTimeStamp()-t))/(float)1000;
    if (p!=3) r=0;
    String c = ""+r+" Secs";
    Label resultat = new Label(c, Label.CENTER);
    add(resultat);
    resultat.setRect(10,10*b+10,160,15);
  }
}
Note 1 : Thanks to Arnaud Farine for providing me with the Jump2 source code and executable.
Note 2 : this source code for Jump2 is adapted from the SuperWaba source code, which was used to generate the Jump2 compiled code.


LaFac - HELP v1.1 - http://www.aldweb.com/ (yeah, that's my work!)

# HBench2s.help
{1$YN/YD$XN\XD=YX+SD}
{2$YN%YD=Y0+SD}
{3ƒT0$P0$N2$WB*W500+W1
(^NW$MN\M2+M1$S1$D2
(^DM=B1@1=B2@2+D1)=SN+P1+N1)
ƒR0ƒY1-RT/RY^P3$R0:R2' Secs'}
$B1(^B3@3+B1)


LaFac - µBAS v1.1 - http://www.aldweb.com/ (yeah, that's my work!)

' MBench2.mbas

PerfectNum:
  T=TICKS
  P=0 : C=B*500
  FOR N=2 TO C
    M=N\2 : S=1
    FOR D=2 TO M
      IF B=1 THEN Y=N/D : X=N\D : IF Y=X THEN S=S+D
      IF B=2 THEN Y=N MOD D : IF Y=0 THEN S=S+D
    NEXT
    IF S=N THEN P=P+1
  NEXT
  R=TICKS-T/TICKSPERSEC
  IF P<>3 THEN R=0
  PRINT R USING 2;
  PRINT " Secs"
RETURN

BEGIN
FOR B=1 TO 2
  GOSUB PerfectNum
NEXT
END


LaFac - µC v1.1 - http://www.aldweb.com/ (yeah, that's my work!)

// CBench2.mc--

void PerfectNum() {
  nT=Ticks();
  nP=0;
  nC=nB*500;
  for(nN=2; nN<=nC; nN++) {
    nM=nN\2;
    nS=1;
    for(nD=2; nD<=nM; nD++) {
      if(nB==1) {
        nY=nN/nD;
        nX=nN\nD;
        if(nY==nX) nS=nS+nD;
      }
      if(nB==2) { 
        nY=nN%nD;
        if(nY==0) nS=nS+nD;
      }
    }
    if(nS==nN) nP++;
  }
  nR=Ticks()-nT/TicksPerSecond();
  if(nP!=3) nR=0;
  puts(nR;2);
  puts(' Secs\n');
}

main() {
  for(nB=1; nB<3; nB++)
    PerfectNum();
}


LaFac - µPAS v1.1 - http://www.aldweb.com/ (yeah, that's my work!)

// PBench2.mpas

Procedure PerfectNum;
begin
  nT:=Ticks;
  nP:=0;
  nC:=nB*500;
  for nN:=2 to nC do begin
    nM:=nN div 2;
    nS:=1;
    for nD:=2 to nM do begin
      if nB=1 then begin
        nY:=nN/nD;
        nX:=nN div nD;
        if nY=nX then nS:=nS+nD;
      end;
      if nB=2 then begin
        nY:=nN mod nD;
        if nY=0 then nS:=nS+nD;
      end;
    end;
    if nS=nN then nP:=nP+1;
  end;
  nR:=Ticks-nT/TicksPerSecond;
  if nP<>3 then nR:=0;
  write(nR,2);
  writeln(' Secs');
end;

begin
  for nB:=1 to 2 do
    PerfectNum;
end.


LispMe v3.21 - http://www.lispme.de/

; Bench 2
(define (start)
  (do ((b 1 (+ b 1))) ((> b 2))
    (perfectnum b)) #n)

(define (perfectnum b)
  (let ((timer (current-ticks))
        (p 0))
    (do ((n 2 (+ n 1))) ((> n (* 500 b)))
      (let ((m (quotient n 2))
            (s 1))
        (do ((d 2 (+ d 1))) ((> d m))
          (if (eq? b 1)
            (if (eq? (/ n d) (quotient n d))
              (set! s (+ s d))))
          (if (eq? b 2)
            (if (eq? (remainder n d) 0)
              (set! s (+ s d)))))
        (if (eq? s n) (set! p (+ p 1)))))
    (let ((t (/ (ticks-since timer) (ticks-per-sec))))
      (if (not (eq? p 3)) (set! t 0))
      (display t) (newline))))
Note : Thanks to Fred Bayer for providing me with the LispMe source code.


LyME v2.8 - http://www.calerga.com/

function bench2
  for b=1:2;
    perfectnum(b);
  end

function perfectnum(c)
  // Perfect Numbers finder routine
  tic
  p=0;
  for n=2:c*500;
    m=floor(n/2);
    s=1;
    for d=2:m;
      if c==1 
         if (n/d)==floor(n/d)
          s=s+d;
        end
      end
      if c==2 
        if mod(n,d)==0
          s=s+d;
        end
      end
    end
    if s==n 
      p=p+1;
    end
  end
  r=toc;
  if p~=3
    r=0;
  end
  sprintf('%.2f %s',r,'Secs')


NaPP Private preview release - http://www.ppcompiler.org/

Program Bench2NaPP;

Var
  B: integer;

Type
  Err=0..65535;

function FlpFToA(a:real;var s:string):Err;
  inline($e519c008,$e1a0e00f,$e59cf3d4);

procedure SysTaskDelay(delay:integer);
  inline($E519C008,$E1A0E00F,$E59CF8E8);

function SysTicksPerSecond:integer;
  inline($E519C008,$E1A0E00F,$E59CF8F4);

function TimGetTicks:integer;
  inline($E519C008,$E1A0E00F,$E59CF928);

procedure WinDrawChars(const chars:string;len,x,y:integer);
  inline($E519C008,$E1A0E00F,$E59CFB18);

Procedure PrintText(const s:string;x,y:integer);
  begin
    WinDrawChars(s,Length(s),x,y);
  end;

Procedure PrintReal(r:real;x,y:integer);
  var
    s:string;
  begin
    FlpFToA(r,s);
    PrintText(s,x,y);
  end;

procedure PerfectNum;
{ Perfect Numbers finder routine }
  var
    N,D,M,S,P,T: integer;
    R: real;
  begin
    T:=TimGetTicks;
    P:=0;
    for N:=2 to B*500 do begin
      M:=N div 2;
      S:=1;
      for D:=2 to M do begin
        if B=1 then if (N/D)=(N div D) then S:=S+D;
        if B=2 then if (N mod D)=0 then S:=S+D;
      end;
      if S=N then P:=P+1;
    end;
    R:=(TimGetTicks-T)/SysTicksPerSecond;
    if P<>3 then R:=0;
//    writeln(R:1:2,' Secs');
    PrintReal(R,10,B*10);
    PrintText('Secs',75,B*10);
  end;

begin
  for B:=1 to 2 do
    PerfectNum;
  SysTaskDelay(5*SysTicksPerSecond);
end.


NS Basic/Palm v3.0.0d - http://www.nsbasic.com/palm

Sub Project_Startup()
  Dim B as Integer
  For B=1 to 2
    GoSub PerfectNum
  Next
  Exit Sub

  PerfectNum:
  ' Perfect Numbers finder routine
    Dim N as Integer
    Dim D as Integer
    Dim M as Integer
    Dim S as Integer
    Dim P as Integer
    Dim T as Integer
    Dim R as Float

    T=SysInfo(1)
    P=0
    For N=2 TO B*500
      M=N/2
      S=1
      For D=2 TO M
        If B=1 Then 
          If (N/D)=int(N/D) Then S=S+D
        EndIf  
        If B=2 Then 
          If mod(N,D)=0 Then S=S+D
        EndIf 
      Next
      If S=N Then P=P+1
    Next
    R=(SysInfo(1)-T)/SysInfo(2)
    If P<>3 Then R=0
    MsgBox Str(R)+" Secs"
  Return
End Sub


OnBoardC v2.4.2 - http://onboardc.sourceforge.net/

int b;

long SysTicksPerSecond()={0x4e4f,0xa2e9};

void PerfectNum() {
// Perfect Numbers finder routine
  int n,d,m,s,p;
  long t;
  float r;
  char c[80],v[80];
  
  t=TimGetTicks();
  p=0;
  for(n=2;n<=b*500;n++) {
    m=n/2;
    s=1;
    for(d=2;d<=m;d++) {
      if(b==1) if((((float)n)/((float)d))==(n/d)) s=s+d;
      if(b==2) if((n%d)==0) s=s+d;
    }
    if(s==n) p=p+1;
  }
  r=((float)(TimGetTicks()-t))/((float)SysTicksPerSecond());
  if(p!=3) r=0;
  StrIToA(c,(int)r);
  StrCat(c,".");
  r=(r-(int)r)*100;
  StrIToA(v,(int)r);
  StrCat(c,v);
  StrCat(c," Secs");
  WinDrawChars(c,StrLen(c),1,10*b);
  return;
} 

DWord PilotMain(Word cmd,Ptr cmdPBP,Word launchFlags) { 
  if (cmd == sysAppLaunchCmdNormalLaunch) {
    for(b=1;b<=2;b++) {
      PerfectNum();
    }
  SysTaskDelay(5*SysTicksPerSecond());
  }
  return 0;
}
Note 1 : Thanks to Philippe Guillot for providing me with the original OnBoardC source code.
Note 2 : OnBoardC converts float type to double type before proceeding with calculation. Therefore, working with the double type is faster. Nevertheless, as explained on the Bench2 main page, I have decided to work with the simple precision type being (float).


OrbForms Designer v2.1.1 - http://www.orbworks.com/

int b;

string PerfectNum() {
// Perfect Numbers finder routine
  int n,d,m,s,p,t;
  float r;
  string c;

  t=ticks();
  p=0;
  for(n=2;n<=b*500;n++) {
    m=n/2;
    s=1;
    for(d=2;d<=m;d++) {
      if(b==1) if((((float)n)/((float)d))==(n/d)) s=s+d;
      if(b==2) if((n%d)==0) s=s+d;
    }
    if (s==n) p=p+1;
  }
  r=((float)(ticks()-t))/((float)100);
  if(p!=3) r=0;
  c=format(r,2);
  return c;
}

handler mainForm.ondraw() {
  Draw draw;
  draw.attachForm(this);
  draw.begin();
  for(b=1;b<=2;b++) {
    draw.text(clrText,1,10+b*10,PerfectNum()+" Secs");
  }
  draw.end();
}

handler app.onstart() {
  mainForm.load();
}
Note 1 : The OrbForms Designer runtime runs much faster than the PocketC runtime, also from OrbWorks, Inc. Jeremy Dewey kindly gave me the reason for this better performance: "The virtual machine between PocketC and OrbForms is much improved as you've noticed. The main difference is that PocketC instructions are untyped, so each instruction must check the types of its operands. In OrbForms, the compiler ensures the types are correct and emits type-specific instructions.".
Note 2 : Thanks to Jeremy Dewey for providing me with a full version of OrbForms Designer for the purpose of this Bench2 analysis.


Palm Basic v1.02 - http://www.thelawrences.org/palmbasic/

for B%=1 to 2
  gosub PerfectNum
next B%
end

PerfectNum:
  T%=time()
  P%=0
  for N%=2 to B%*500
    M%=N%/2
    S%=1
    for D%=2 to M%
      if B%=1 then if (N%/D%)=int(N%/D%) then S%=S%+D%
      if B%=2 then if (N%-int(N%/D%)*D%)=0 then S%=S%+D%
    next D%
    if S%=N% then P%=P%+1
  next N%
  R%=time()-T%
  if P%<>3 then R%=0
  print R%;" Secs"
return
Note : Palm Basic does not have a modulo operator. This is why loop [ if B=2 then if (N modulo D)=0 then S = S+D ] cannot be run as is. Replacing it with [ if B=2 then if (N-(N div D)*D)=0 then S = S+D ] provides with an equivalent formula.


Palm Tcl v0.4 - http://palm-tcl.sourceforge.net/

APPLICATIONICONNAME ID 3 "Bench2"
APPLICATION ID 2 "BEN2"
VERSION ID 3 "1.0"

FORM ID 1000 AT(0 0 160 160)
NOFRAME
BEGIN
  FIELD ID 1001 AT(1 1 50 15) USABLE LEFTALIGN FONT 0 NONEDITABLE SINGLELINE
  LABEL "Secs" ID 1002 AT(51 1) USABLE FONT 0
  FIELD ID 1003 AT(1 11 50 15) USABLE LEFTALIGN FONT 0 NONEDITABLE SINGLELINE
  LABEL "Secs" ID 1004 AT(51 11) USABLE FONT 0
END

STRING ID 9999 "global N \n" \
               "global D \n" \ 
               "global M \n" \
               "global S \n" \
               "global P \n" \
               "global T \n" \
               "global R \n" \
               "proc perfectnum {B} { \n" \
               "# Perfect Numbers finder routine \n" \
               "  set T [clock clicks] \n" \
               "  set P 0 \n" \
               "  for {set N 2} {$N <= [expr $B*500]} {incr N} { \n" \
               "    set M [expr $N/2] \n" \
               "    set S 1 \n" \
               "    for {set D 2} {$D <= $M} {incr D} { \n" \
               "      if {$B==1} {if {(double($N)/double($D))==($N/$D)} {set S [expr $S+$D]}} \n" \
               "      if {$B==2} {if {($N%$D)==0} {set S [expr $S+$D]}} \n" \
               "    } \n" \
               "    if {$S==$N} {set P [expr $P+1]} \n" \
               "  } \n" \
               "  set R [expr (double([clock clicks])-double($T))/double([clock clicks -rate])] \n" \
               "  if {$P!=3} {set R 0} \n" \
               "  return $R \n" \
               "} \n" \
               "set form [form load 1000] \n" \
               "$form set 1001 [string trimleft [perfectnum 1]] \n" \
               "$form set 1003 [string trimleft [perfectnum 2]] \n" \
               "$form display \n"


picoBASIC Integer v1.01 - http://www.picodoc.com/samples/picobasic/picobasici.html

10 ' Bench2
20 FOR B=1 TO 2
30 GOSUB 60
40 NEXT
50 END
60 ' Perfect Numbers finder routine
70 T$=TIME$
80 P=0
90 FOR N=2 TO B*500
100 M=N/2
110 S=1
120 FOR D=2 TO M
130 IF B=1 THEN IF (N-(N/D)*D)=0 THEN S=S+D
140 IF B=2 THEN IF (N MOD D)=0 THEN S=S+D
150 NEXT
160 IF S=N THEN P=P+1
170 NEXT
180 R$=TIME$
190 R1=VAL(LEFT$(R$,2))-VAL(LEFT$(T$,2))
200 R2=VAL(MID$(R$,4,2))-VAL(MID$(T$,4,2))
210 R3=VAL(RIGHT$(R$,2))-VAL(RIGHT$(T$,2))
220 R=3600*R1+60*R2+R3
230 IF P<>3 THEN R=0
240 PRINT STR$(R)+" Secs"
250 RETURN
Note : picoBASIC only works with integer numbers. This is why loop [ IF B=1 THEN IF (N/D)=(N\D) THEN S=S+D ] cannot be run as is. Replacing it with [ IF B=1 THEN IF (N-(N/D)*D)=0 THEN S=S+D ] gives a a way of not removing picoBASIC from the Bench2 comparizon even if it cannot be compared exactly with the others. It does not really matter as picoBASIC is anyway by far the slowliest developement tool!


PLua v1.0 - http://netpage.em.com.br/mmand/plua.htm

-- Bench2.lua

function PerfectNum(c)
-- Perfect Numbers finder routine
  local n,d,m,s,p,t
  t=3600*date("%H")+60*date("%M")+date("%S")
  p=0
  for n=2,c*500 do
    m=floor(n/2)
    s=1
    for d=2,m do
      if c==1 then
        if (n/d)==floor(n/d) then
          s=s+d
        end
      end
      if c==2 then
        if mod(n,d)==0 then
          s=s+d
        end
      end
    end
    if s==n then
      p=p+1
    end
  end
  r=3600*date("%H")+60*date("%M")+date("%S")-t
  if p~=3 then
    r=0
  end
  print(r,"Secs")
end

for b=1,2 do
  PerfectNum(b)
end
pevent()


PocketC v6.0.0 - http://www.orbworks.com/

// Bench2

int b;

PerfectNum() {
// Perfect Numbers finder routine
  int n,d,m,s,p,t;
  float r;
  string c;

  t=ticks();
  // Perfect Numbers finder routine
  p=0;
  for(n=2;n<=b*500;n++) {
    m=n/2;
    s=1;
    for(d=2;d<=m;d++) {
      if(b==1) if((((float)n)/((float)d))==(n/d)) s=s+d;
      if(b==2) if((n%d)==0) s=s+d;
    }
    if (s==n) p=p+1;
  }
  r=((float)(ticks()-t))/((float)getsysval(4));
  if(p!=3) r=0;
  c=format(r,2);
  text(1,10+b*10,c+" Secs");  
}

main() {
  graph_on();
  title("Bench2");
  for(b=1;b<=2;b++) {
    PerfectNum();
  }
  waitp();
}
Note 1 : I was surprised to see that the result is a little bit better in the graphics form than in the basic output form.
Note 2 : My second surprise was to see that results were a little bit better in the earlier version 4.4.1 of PocketC. I received from Jeremy Dewey the following explanation about this: "PocketC 5 added an additional instruction to the function prolog and epilog and a slight change to the memory model, which slows stuff down a bit (but allowed for larger apps), so this is partially expected.".
Note 3 : Thanks to Jeremy Dewey for providing me with a full version of PocketC for the purpose of this Bench2 analysis.


PocketC Architect v1.0 - http://www.orbworks.com/

@app myApp {
  creator = "LDB2";
  name = "Bench2";
  dbname = "Bench2";
}

@form myForm {
  id = 1000
  text = "Bench2"
  x = 0, y = 0, w = 160, h = 160
}


int b;

string PerfectNum() {
// Perfect Numbers finder routine
  int n,d,m,s,p,t;
  float r;
  string c;

  t=ticks();
  p=0;
  for(n=2;n<=b*500;n++) {
    m=n/2;
    s=1;
    for(d=2;d<=m;d++) {
      if(b==1) if((((float)n)/((float)d))==(n/d)) s=s+d;
      if(b==2) if((n%d)==0) s=s+d;
    }
    if (s==n) p=p+1;
  }
  r=((float)(ticks()-t))/((float)100);
  if(p!=3) r=0;
  c=format(r,2);
  return c;
}

handler myForm.ondraw() {
  Draw draw;
  draw.attachForm(this);
  draw.begin();
  for(b=1;b<=2;b++) {
    draw.text(clrText,1,10+b*10,PerfectNum()+" Secs");
  }
  draw.end();
}

handler myApp.onstart() {
  myForm.load();
}
Note : Thanks to Christopher Hill for providing me with the PocketC Architect source code and executable.


PocketStudio v1.1 - http://www.winsoft.sk/

program Bench2;

{$CREATOR 'BEN2'}

uses
  Window,
  StringMgr,
  SystemMgr,
  TimeMgr;

var
  B: Integer;

procedure PerfectNum;
{ Perfect Numbers finder routine }
  var
    N,D,M,S,P: Integer;
    T: LongWord;
    R: Real;
    C,V: array [0..80] of Char;
  begin
    T:=TimGetTicks;
    P:=0;
    for N:=2 to B*500 do begin
      M:=N div 2;
      S:=1;
      for D:=2 to M do begin
        if B=1 then if (N/D)=(N div D) then S:=S+D;
        if B=2 then if (N mod D)=0 then S:=S+D;
      end;
      if S=N then P:=P+1;
    end;
    R:=(TimGetTicks-T)/SysTicksPerSecond;
    if P<>3 then R:=0;
    StrIToA(C,trunc(R));
    StrCat(C,'.');
    R:=(R-trunc(R))*100;
    StrItoA(V,round(R));
    StrCat(C,V);
    StrCat(C,' Secs');
    WinDrawChars(C,StrLen(C),1,10+B*10);
  end;


begin
  for B:=1 to 2 do
    PerfectNum;
  SysTaskDelay(5*SysTicksPerSecond);
end.


PP v2.08q - http://www.ppcompiler.org/

Program Bench2;

Var
  B: integer;

function SysTicksPerSecond:integer;
  inline($4E4F,$A2E9);

function TimGetTicks:integer;
  inline($4E4F,$A0F7);

procedure PerfectNum;
{ Perfect Numbers finder routine }
  var
    N,D,M,S,P,T: integer;
    R: real; 
  begin
    T:=TimGetTicks;
    P:=0;
    for N:=2 to B*500 do begin
      M:=N div 2;
      S:=1;
      for D:=2 to M do begin
        if B=1 then if (N/D)=(N div D) then S:=S+D;
        if B=2 then if (N mod D)=0 then S:=S+D;
      end;
      if S=N then P:=P+1;
    end;
    R:=(TimGetTicks-T)/SysTicksPerSecond;
    if P<>3 then R:=0;
    writeln(R:1:2,' Secs');
  end;

begin
  for B:=1 to 2 do
    PerfectNum;
end.

{$appl BEN2}
program Bench2Arm(cmd);
{$i PalmARM.pas}

var
  Cmd: UInt16; 
  Fake:integer;

procedure write(S:string;X,Y:integer);
var
  N:integer;
begin
  N:=length(S);
  WinDrawChars(S,N,X,Y);
end;
 
begin
  if cmd=0 then begin 
    if VersionSupported(V500) then
      NativeCall(ARMrsrc,1,Fake)
    else
      write('Sorry, Palm OS 5 required.',1,1);
    SysTaskDelay(5*SysTicksPerSecond);
  end;    
end.

{$armlet appl,BEN2,armp,1} program Bench2Arm; {$i PPlibARM.pas} type Int16 = -32768..32767; UInt16 = 0..65535; UInt32 = 0..MaxInt; var B:integer; function SysTicksPerSecond:UInt16; SYSTRAP $2E9; function TimGetTicks:UInt32; SYSTRAP $0F7; procedure WinDrawChars(const chars:string;len:Int16;x,y:UInt16); SYSTRAP $220; procedure write(S:string;X,Y:integer); var N:integer; begin N:=length(S); WinDrawChars(S,N,X,Y); end; procedure PerfectNum; { Perfect Numbers finder routine } var N,D,M,S,P,T:integer; R:real; begin T:=TimGetTicks; P:=0; for N:=2 to B*500 do begin M:=N div 2; S:=1; for D:=2 to M do begin if B=1 then if (N/D)=(N div D) then S:=S+D; if B=2 then if (N mod D)=0 then S:=S+D; end; if S=N then P:=P+1; end; R:=(TimGetTicks-T)/SysTicksPerSecond; if P<>3 then R:=0; write(RealToFix(R,2)+' Secs',1,1+B*10); end; begin for B:=1 to 2 do PerfectNum; end.


Quartus Forth v1.2.1 - http://www.quartus.net/

\ bench2
needs double
needs dblmath
needs float-ext

variable p
variable s
variable b
2variable t

: f/=i/? ( s s -- f )
  2dup 
  >r s>d d>f r>  s>d d>f f/ 
  / s>d d>f f- f0=
; inline

: nbparf ( b -- )
  TimGetTicks t 2!
  dup b !
  0 p !
  500 * 1+ 2  ?do ( n index de boucle )
    1 s !
    i 2 / 1+  
    2 ?do ( d index de boucle )
      b @ dup
      1 = if 
         j i f/=i/?  if s @ i + s ! then
      then
      2 = if
         j  i mod 0= if s @ i + s ! then
       then
     loop
     i s @ = if 
       p @ 1 + p !
     then
  loop
  p @ 3 = 0= if ." raté" cr else
    TimGetTicks t 2@ d-
    ." bench2, b=" b @ .  ." ticks " d. cr
  then
;

: bench2
  3 1 do
    i nbparf
  loop
;
Note : Thanks to Marc Furrer for providing me with the Quartus Forth source code and executable.


REXX / PALM OS v1.00 - http://www.jaxo.com/rexx/

/* Bench2 */
do B=1 to 2
  call PerfectNum
end
exit

PerfectNum:
/* Perfect Number finder routine */
  T=time('R')
  P=0
  do N=2 to B*500
    M=N%2
    S=1
    do D=2 to M
      if B=1 then if (N/D)=(N%D) then S=S+D
      if B=2 then if (N//D)=0 then S=S+D 
    end
    if S=N then P=P+1
  end
  R=time('E')
  if P\=3 then R=0
  say R "Secs"
return


Satellite Forms v5.0.0 - http://www.pumatech.com/

'To put in AfterAppStart Global Script
Dim B
For B=1 to 2
  PerfectNum(B) 
Next

'To put in Funcs & Subs (Shared) Global Script
Sub PerfectNum(C)
' Perfect Numbers finder routine
    Dim N
    Dim D
    Dim M
    Dim S
    Dim P
    Dim T
    Dim R

    T=GetTickCount
    P=0
    For N=2 TO C*500
    M=N\2
      S=1
      For D=2 TO M
        If C=1 Then 
          If (N/D)=(N\D) Then S=S+D
        EndIf
        If C=2 Then 
          If (N Mod D)=0 Then S=S+D
        EndIf 
      Next D
      If S=N Then P=P+1
    Next N
    R=(GetTickCount-T)/GetTickFrequency
    If P<>3 Then R=0
    MsgBox(Str(R)&" Secs")
End Sub


SmallBASIC v0.8.2 - http://smallbasic.sourceforge.net/

FOR B=1 TO 2
  PERFECTNUM
NEXT
END

SUB PERFECTNUM
' Perfect Numbers finder routine
  LOCAL N,D,M,S,P,T,R
  T=TICKS
  P=0
  FOR N=2 TO B*500
    M=N\2
    S=1
    FOR D=2 TO M
      IF B=1 THEN IF (N/D)=(N\D) THEN S=S+D
      IF B=2 THEN IF (N MOD D)=0 THEN S=S+D
    NEXT
    IF S=N THEN P=P+1
  NEXT
  R=(TICKS-T)/TICKSPERSEC
  IF P<>3 THEN R=0
  PRINT R+" Secs"
END


Sun MIDP v1.0 - http://java.sun.com/products/midp4palm/

import javax.microedition.midlet.*; 
import javax.microedition.lcdui.*;

public class BenchJTwoMe extends MIDlet implements CommandListener {
  private Display midletDisplay;
  private Command doneCommand;
  TextBox textBox;
  
  public BenchJTwoMe() {
    midletDisplay = Display.getDisplay(this);
    doneCommand = new Command("OK", Command.SCREEN, 1);
  } 
  
  public void startApp() {
    textBox = new TextBox("BenchJTwoMe2", "", 256, 0);
    textBox.addCommand(doneCommand); 
    textBox.setCommandListener( (CommandListener) this); 
    midletDisplay.setCurrent(textBox); 
    for(int b=1;b<=2;b++) {
      benchmark(b);
    }
  }
 
  private void benchmark(int b) {
    long t = System.currentTimeMillis();
    int p = 0;
    for (int n=2;n<=b*500;n++) {
      int m = n/2;
      int s = 1;
      for (int d=2;d<=m;d++) {
        if (b==1) if ((n-(n/d)*d)==0) s=s+d;
        if (b==2) if (n%d == 0) s=s+d;
      }
      if (s==n) p=p+1;
    }
    
    long r = System.currentTimeMillis()-t;
    if (p!=3) r=0;
    long v = r/1000;
    String c = ""+v+".";
    r=r-v*1000;
    c=c+r+" Secs\n";
    textBox.setString(textBox.getString() + c);
  }

  public void pauseApp() {
  }

  public void destroyApp(boolean unconditional) { 
  } 

  public void commandAction(Command command, Displayable screen) {
    if (command == doneCommand) {
      destroyApp(false);
      notifyDestroyed(); 
    } 
  } 
} 
Note 1 : Thanks to Arnaud Farine for providing me with the Sun MIDP source code and executable.
Note 2 : It seems that J2ME can natively only work with integer numbers. This is why loop [ if (b==1) if (((float)n)/((float)d) == n/d) s=s+d; ] cannot be run as is. Replacing it with [ if (b==1) if ((n-(n/d)*d)==0) s=s+d; ] gives a a way of not removing J2ME from the Bench2 comparizon even if it cannot be compared exactly with the others.


SuperWaba v4.21b - http://www.superwaba.org/

import waba.ui.*;
import waba.fx.*;
import waba.sys.Vm;
import waba.sys.Settings;

public class BenchSuperwaba extends MainWindow {
  Color cBack = Color.WHITE;
  Color cFore = Color.BLACK;
  int multiX = Settings.screenWidth/160;
  int multiY = Settings.screenHeight/160;

  public BenchSuperwaba() {
    setTitle("Bench2-Superwaba");
    setBackColor(cBack);
    setForeColor(cFore);
    Label resultat = new Label("", Label.CENTER);
    add(resultat);
    resultat.setRect(10,10,160*multiX,15*multiY);
    for(int b=1;b<=2;b++) {
      benchmark(b);
    }
  }

  private void benchmark(int b) {
    int t = Vm.getTimeStamp();
    int p = 0;
    for (int n=2;n<=b*500;n++) {
      int m = n/2;
      int s = 1;
      for (int d=2;d<=m;d++){
        if (b==1) if (((float)n)/((float)d) == n/d) s=s+d;
        if (b==2) if (n%d == 0) s=s+d;
      }
      if (s==n) p=p+1;
    }
    float r = ((float)(Vm.getTimeStamp()-t))/(float)1000;
    if (p!=3) r=0;
    String c = ""+r+" Secs";
    Label resultat = new Label(c, Label.CENTER); 
    add(resultat);
    resultat.setRect(CENTER,AFTER,160*multiX,15*multiY);
  }
}
Note : Thanks to Arnaud Farine for providing me with the SuperWaba source code and executable.