Delphi Vs C++

Associate
Joined
20 Jun 2004
Posts
1,002
Location
Manchester
Hi Guys,

I need to check your knowledge for a bit, because i'm coming up at a brick wall.

Been doing an assignment for university on 'benchmarking' where we ran two little programs and gathered the time it took for 1 iteration of a loop running a calculation (addition, subtraction, multiplication and division)

Anyway, the Delphi programmed benchmarker always provided quicker times compared to the C++ programmed one.

Our lecturer is absolutely useless and giving us no support for it at all. Do you know of any reason why Delphi/Pascal code is quicker to run than C++ code? I enclose the two segments of code for your perusal, but by my gathering they look pretty much the same, apart from given differences in writing.

C++
Code:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "time06.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm2::BtnAddClick(TObject *Sender)
{
SYSTEMTIME myTime;
int n,m,loops,powerOf10;
int a,b,c;
double x,y,z;
int timeStart, timeEnd;
loops=1 ;
powerOf10 = StrToInt(EdtPowerOfTen->Text);
for(m=0;m<powerOf10;m++)loops=loops*10;

GetLocalTime(&myTime);
Edit1->Text = IntToStr(myTime.wMinute)+':'+
              IntToStr(myTime.wSecond)+':'+
              IntToStr(myTime.wMilliseconds);

timeStart = myTime.wSecond*1000+myTime.wMilliseconds;

if (RBtnInteger->Checked)
  for(n=0; n<loops; n= n+1) a = b+c;     // Integer operations

if (RBtnFloat->Checked)
  for(n=0; n<loops; n= n+1) x = y+z ;

GetLocalTime(&myTime);
Edit2->Text = IntToStr(myTime.wMinute)+':'+
              IntToStr(myTime.wSecond)+':'+
              IntToStr(myTime.wMilliseconds);

timeEnd = myTime.wSecond*1000+myTime.wMilliseconds;

Edit3->Text=IntToStr(timeEnd-timeStart);
Edit4->Text=FloatToStrF((timeEnd-timeStart)*1e6/loops,ffExponent,3,2);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
SYSTEMTIME myTime;
int n,m,loops,powerOf10;
int a,b,c;
double x,y,z;
int timeStart, timeEnd;
loops=1 ;
powerOf10 = StrToInt(EdtPowerOfTen->Text);
for(m=0;m<powerOf10;m++)loops=loops*10;

GetLocalTime(&myTime);
Edit1->Text = IntToStr(myTime.wMinute)+':'+
              IntToStr(myTime.wSecond)+':'+
              IntToStr(myTime.wMilliseconds);

timeStart = myTime.wSecond*1000+myTime.wMilliseconds;

for(n=0; n<loops; n= n+1){
// a = b /c;      // Integer operations
// a = b*c;
 x = y/z;       // Real operations
 // x = y*z;
 // x = cos(.5);
 // x = log(100);
// Form2->Caption = StrToInt(n);
 // Memo1->Lines->SaveToFile("temp.tmp");

}
GetLocalTime(&myTime);
Edit2->Text = IntToStr(myTime.wMinute)+':'+
              IntToStr(myTime.wSecond)+':'+
              IntToStr(myTime.wMilliseconds);

timeEnd = myTime.wSecond*1000+myTime.wMilliseconds;

Edit3->Text=IntToStr(timeEnd-timeStart);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::BtnSubtractClick(TObject *Sender)
{
SYSTEMTIME myTime;
int n,m,loops,powerOf10;
int a,b,c;
double x,y,z;
int timeStart, timeEnd;
loops=1 ;
powerOf10 = StrToInt(EdtPowerOfTen->Text);
for(m=0;m<powerOf10;m++)loops=loops*10;

GetLocalTime(&myTime);
Edit1->Text = IntToStr(myTime.wMinute)+':'+
              IntToStr(myTime.wSecond)+':'+
              IntToStr(myTime.wMilliseconds);

timeStart = myTime.wSecond*1000+myTime.wMilliseconds;

if (RBtnInteger->Checked)
  for(n=0; n<loops; n= n+1) a = b-c;     // Integer operation

if (RBtnFloat->Checked)
  for(n=0; n<loops; n= n+1) x = y-z ;    //Float opertion

GetLocalTime(&myTime);
Edit2->Text = IntToStr(myTime.wMinute)+':'+
              IntToStr(myTime.wSecond)+':'+
              IntToStr(myTime.wMilliseconds);

timeEnd = myTime.wSecond*1000+myTime.wMilliseconds;

Edit3->Text=IntToStr(timeEnd-timeStart);
Edit4->Text=FloatToStrF((timeEnd-timeStart)*1e6/loops,ffExponent,3,2);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::BtnMultiplyClick(TObject *Sender)
{
SYSTEMTIME myTime;
int n,m,loops,powerOf10;
int a,b,c;
double x,y,z;
int timeStart, timeEnd;
loops=1 ;
powerOf10 = StrToInt(EdtPowerOfTen->Text);
for(m=0;m<powerOf10;m++)loops=loops*10;

GetLocalTime(&myTime);
Edit1->Text = IntToStr(myTime.wMinute)+':'+
              IntToStr(myTime.wSecond)+':'+
              IntToStr(myTime.wMilliseconds);

timeStart = myTime.wSecond*1000+myTime.wMilliseconds;

if (RBtnInteger->Checked)
  for(n=0; n<loops; n= n+1) a = b*c;     // Integer operations

if (RBtnFloat->Checked)
  for(n=0; n<loops; n= n+1) x = y*z ;

GetLocalTime(&myTime);
Edit2->Text = IntToStr(myTime.wMinute)+':'+
              IntToStr(myTime.wSecond)+':'+
              IntToStr(myTime.wMilliseconds);

timeEnd = myTime.wSecond*1000+myTime.wMilliseconds;

Edit3->Text=IntToStr(timeEnd-timeStart);
Edit4->Text=FloatToStrF((timeEnd-timeStart)*1e6/loops,ffExponent,3,2);        
}
//---------------------------------------------------------------------------
void __fastcall TForm2::BtnDivideClick(TObject *Sender)
{
SYSTEMTIME myTime;
int n,m,loops,powerOf10;
int a,b,c;
double x,y,z;
int timeStart, timeEnd;
loops=1 ;
powerOf10 = StrToInt(EdtPowerOfTen->Text);
for(m=0;m<powerOf10;m++)loops=loops*10;

GetLocalTime(&myTime);
Edit1->Text = IntToStr(myTime.wMinute)+':'+
              IntToStr(myTime.wSecond)+':'+
              IntToStr(myTime.wMilliseconds);

timeStart = myTime.wSecond*1000+myTime.wMilliseconds;

if (RBtnInteger->Checked)
  for(n=0; n<loops; n= n+1) a = b/c;     // Integer operations

if (RBtnFloat->Checked)
  for(n=0; n<loops; n= n+1) x = y/z ;

GetLocalTime(&myTime);
Edit2->Text = IntToStr(myTime.wMinute)+':'+
              IntToStr(myTime.wSecond)+':'+
              IntToStr(myTime.wMilliseconds);

timeEnd = myTime.wSecond*1000+myTime.wMilliseconds;

Edit3->Text=IntToStr(timeEnd-timeStart);
Edit4->Text=FloatToStrF((timeEnd-timeStart)*1e6/loops,ffExponent,3,2);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::BtnEmptyClick(TObject *Sender)
{
SYSTEMTIME myTime;
int n,m,loops,powerOf10;
int a,b,c;
double x,y,z;
int timeStart, timeEnd;
loops=1 ;
powerOf10 = StrToInt(EdtPowerOfTen->Text);
for(m=0;m<powerOf10;m++)loops=loops*10;

GetLocalTime(&myTime);
Edit1->Text = IntToStr(myTime.wMinute)+':'+
              IntToStr(myTime.wSecond)+':'+
              IntToStr(myTime.wMilliseconds);

timeStart = myTime.wSecond*1000+myTime.wMilliseconds;

if (RBtnInteger->Checked)
  for(n=0; n<loops; n= n+1) ;

if (RBtnFloat->Checked)
  for(n=0; n<loops; n= n+1)  ;

GetLocalTime(&myTime);
Edit2->Text = IntToStr(myTime.wMinute)+':'+
              IntToStr(myTime.wSecond)+':'+
              IntToStr(myTime.wMilliseconds);

timeEnd = myTime.wSecond*1000+myTime.wMilliseconds;

Edit3->Text=IntToStr(timeEnd-timeStart);
Edit4->Text=FloatToStrF((timeEnd-timeStart)*1e6/loops,ffExponent,3,2);
}
//---------------------------------------------------------------------------

Delphi
Code:
unit time06;

interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    BtnAdd: TButton;
    BtnSubtract: TButton;
    BtnMultiply: TButton;
    BtnDivide: TButton;
    RGrpType: TRadioGroup;
    RBtnInteger: TRadioButton;
    RBtnReal: TRadioButton;
    EdtPowerOfTen: TEdit;
    Label4: TLabel;
    Edit4: TEdit;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    BtnEmpty: TButton;
    procedure Button1Click(Sender: TObject);
    procedure BtnAddClick(Sender: TObject);
    procedure BtnSubtractClick(Sender: TObject);
    procedure BtnMultiplyClick(Sender: TObject);
    procedure BtnDivideClick(Sender: TObject);
    procedure RBtnIntegerClick(Sender: TObject);
    procedure RBtnRealClick(Sender: TObject);
    procedure BtnEmptyClick(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  h, m, s, hund : Word;
  a, b, c : Real;
  startTime, endTime : LongInt;
  x, y, z : Integer;

implementation
{$R *.DFM}

// allow timing of selected PC activities
// modified 23 Nov 2005
procedure TForm1.Button1Click(Sender: TObject);
var myTime: SYSTEMTIME;
  i, PowerOfTen : integer;
  n,loops : LongInt;
begin
 PowerOfTen := StrToInt(EdtpowerOfTen.Text);
 loops := 1;
 for i:=1 to PowerOfTen do loops := loops*10;
 getsystemtime(myTime);    // get time from operating system
 startTime := myTime.wminute*60000 + myTime.wSecond*1000 + myTime.wMilliseconds;
 Edit1.Text :=  InttoStr(MyTime.wminute) + ':' +  InttoStr(myTime.wsecond) +
                  '.'+ InttoStr(myTime.wMilliseconds);
  a := 0.5;       b := 1.1;          c := 2.2;
  x := 1;         y := 2;
  for n := 1 to loops do        // see lab sheet for suggested n values
   begin
   // z := x + y ;               // Integer arithmetic
   // z := x div y ;
   a := b + c ;              // Real arithmetic
  a := b/c ;
   // a := cos(b);
   // a := ln(c);
   // Form1.Caption := InttoStr(n); //edit these out when doing arithmetic tests

   end;

  getsystemtime(myTime);
  endTime := myTime.wminute*60000 + myTime.wsecond*1000 + myTime.wMilliseconds;
  Edit2.Text :=  InttoStr(myTime.wminute)+':'+ InttoStr(myTime.wsecond) +
                                           ':'+ InttoStr(myTime.wMilliseconds);
  Edit3.Text := InttoStr( EndTime - startTime);
end;



procedure TForm1.BtnAddClick(Sender: TObject);
var myTime: SYSTEMTIME;
  i, PowerOfTen : integer;
  n,loops : LongInt;
begin
 PowerOfTen := StrToInt(EdtpowerOfTen.Text);
 loops := 1;
 for i:=1 to PowerOfTen do loops := loops*10;
 getsystemtime(myTime);    // get time from operating system
 startTime := myTime.wminute*60000 + myTime.wSecond*1000 + myTime.wMilliseconds;
 Edit1.Text :=  InttoStr(MyTime.wminute) + ':' +  InttoStr(myTime.wsecond) +
                  '.'+ InttoStr(myTime.wMilliseconds);
  x := 1;         y := 2;    b:= 3.0; c := 5.0;

  if RBtnInteger.Checked then
  for n := 1 to loops do   z := x + y ;               // Integer add

  if RBtnReal.Checked then
  for n := 1 to loops do   a := b + c ;               // Real add

  getsystemtime(myTime);
  endTime := myTime.wminute*60000 + myTime.wsecond*1000 + myTime.wMilliseconds;
  Edit2.Text :=  InttoStr(myTime.wminute)+':'+ InttoStr(myTime.wsecond) +
                                           ':'+ InttoStr(myTime.wMilliseconds);
  Edit3.Text := InttoStr( EndTime - startTime);
  Edit4.Text := FloatToStrF(((EndTime - startTime)*1e6)/loops,ffExponent,3,8) ;
end;

procedure TForm1.BtnSubtractClick(Sender: TObject);
var myTime: SYSTEMTIME;
  i, PowerOfTen : integer;
  n,loops : LongInt;
begin
 PowerOfTen := StrToInt(EdtpowerOfTen.Text);
 loops := 1;
 for i:=1 to PowerOfTen do loops := loops*10;
 getsystemtime(myTime);    // get time from operating system
 startTime := myTime.wminute*60000 + myTime.wSecond*1000 + myTime.wMilliseconds;
 Edit1.Text :=  InttoStr(MyTime.wminute) + ':' +  InttoStr(myTime.wsecond) +
                  '.'+ InttoStr(myTime.wMilliseconds);
  x := 1;         y := 2;    b:= 3.0; c := 5.0;

  if RBtnInteger.Checked then
  for n := 1 to loops do   z := x - y ;               // Integer add

  if RBtnReal.Checked then
  for n := 1 to loops do   a := b - c ;               // Real add

  getsystemtime(myTime);
  endTime := myTime.wminute*60000 + myTime.wsecond*1000 + myTime.wMilliseconds;
  Edit2.Text :=  InttoStr(myTime.wminute)+':'+ InttoStr(myTime.wsecond) +
                                           ':'+ InttoStr(myTime.wMilliseconds);
  Edit3.Text := InttoStr( EndTime - startTime);
  Edit4.Text := FloatToStrF(((EndTime - startTime)*1e6)/loops,ffExponent,3,8) ;

end;

procedure TForm1.BtnMultiplyClick(Sender: TObject);
var myTime: SYSTEMTIME;
  i, PowerOfTen : integer;
  n,loops : LongInt;
begin
 PowerOfTen := StrToInt(EdtpowerOfTen.Text);
 loops := 1;
 for i:=1 to PowerOfTen do loops := loops*10;
 getsystemtime(myTime);    // get time from operating system
 startTime := myTime.wminute*60000 + myTime.wSecond*1000 + myTime.wMilliseconds;
 Edit1.Text :=  InttoStr(MyTime.wminute) + ':' +  InttoStr(myTime.wsecond) +
                  '.'+ InttoStr(myTime.wMilliseconds);
  x := 1;         y := 2;     b:= 3.0; c := 5.0;

  if RBtnInteger.Checked then
  for n := 1 to loops do   z := x * y ;               // Integer add

  if RBtnReal.Checked then
  for n := 1 to loops do   a := b * c ;               // Real add

  getsystemtime(myTime);
  endTime := myTime.wminute*60000 + myTime.wsecond*1000 + myTime.wMilliseconds;
  Edit2.Text :=  InttoStr(myTime.wminute)+':'+ InttoStr(myTime.wsecond) +
                                           ':'+ InttoStr(myTime.wMilliseconds);
  Edit3.Text := InttoStr( EndTime - startTime);
  Edit4.Text := FloatToStrF(((EndTime - startTime)*1e6)/loops,ffExponent,3,8) ;

end;

procedure TForm1.BtnDivideClick(Sender: TObject);
var myTime: SYSTEMTIME;
  i, PowerOfTen : integer;
  n,loops : LongInt;
begin
 PowerOfTen := StrToInt(EdtpowerOfTen.Text);
 loops := 1;
 for i:=1 to PowerOfTen do loops := loops*10;
 getsystemtime(myTime);    // get time from operating system
 startTime := myTime.wminute*60000 + myTime.wSecond*1000 + myTime.wMilliseconds;
 Edit1.Text :=  InttoStr(MyTime.wminute) + ':' +  InttoStr(myTime.wsecond) +
                  '.'+ InttoStr(myTime.wMilliseconds);
  x := 1;  y := 2;   b:= 3.0; c := 5.0;
  if RBtnInteger.Checked then
  for n := 1 to loops do   z := x div y ;               // Integer divide

  if RBtnReal.Checked then
  for n := 1 to loops do
  a := b/c ;               // Real divide

  getsystemtime(myTime);
  endTime := myTime.wminute*60000 + myTime.wsecond*1000 + myTime.wMilliseconds;
  Edit2.Text :=  InttoStr(myTime.wminute)+':'+ InttoStr(myTime.wsecond) +
                                           ':'+ InttoStr(myTime.wMilliseconds);
  Edit3.Text := InttoStr( EndTime - startTime);
  Edit4.Text := FloatToStrF(((EndTime - startTime)*1e6)/loops,ffExponent,3,8) ;

end;

procedure TForm1.RBtnIntegerClick(Sender: TObject);
begin
  BtnDivide.Caption := 'div';
end;

procedure TForm1.RBtnRealClick(Sender: TObject);
begin
  BtnDivide.Caption := '\';
end;

procedure TForm1.BtnEmptyClick(Sender: TObject);
var myTime: SYSTEMTIME;
  i, PowerOfTen : integer;
  n,loops : LongInt;
begin
 PowerOfTen := StrToInt(EdtpowerOfTen.Text);
 loops := 1;
 for i:=1 to PowerOfTen do loops := loops*10;
 getsystemtime(myTime);    // get time from operating system
 startTime := myTime.wminute*60000 + myTime.wSecond*1000 + myTime.wMilliseconds;
 Edit1.Text :=  InttoStr(MyTime.wminute) + ':' +  InttoStr(myTime.wsecond) +
                  '.'+ InttoStr(myTime.wMilliseconds);
  x := 1;  y := 2;   b:= 3.0; c := 5.0;
  if RBtnInteger.Checked then
  for n := 1 to loops do   ;

  if RBtnReal.Checked then
  for n := 1 to loops do   ;

  getsystemtime(myTime);
  endTime := myTime.wminute*60000 + myTime.wsecond*1000 + myTime.wMilliseconds;
  Edit2.Text :=  InttoStr(myTime.wminute)+':'+ InttoStr(myTime.wsecond) +
                                           ':'+ InttoStr(myTime.wMilliseconds);
  Edit3.Text := InttoStr( EndTime - startTime);
  Edit4.Text := FloatToStrF(((EndTime - startTime)*1e6)/loops,ffExponent,3,8) ;

end;

end.

If you could provide any insight at all i'd be greatful.
 
it was precompiled mate, i couldn't actually tell you what was turned on, other than it was probably done in Borland CBulider as thats what they use at our uni.
 
So would that be a good reason to explain why the code is executed more efficient in Delphi? A more efficient compilation process?
 
It's one reason. If I knew Delphi/Pascal then I'd look at the code. There must be something in the code too.
 
Hi,

From looking at the code I think too much "unknown" is going on to come to any conclusion that Delphi is quicker etc. (I don't know enough Delphi to say if the code is good, bad etc).

For example, both programs use VCL controls, so some of the difference could be down to how the different routines in the Delphi/C++ compiled code implement these. Otherwise you're narrowing the benchmark to comparing "Delphi/C++ code that uses VCL". It shouldn't make much difference as your timings don't include any drawing/Window handling code etc, but some VCL related processing could be being done in the background.

It could also be that the version of compiler used to compile the Delphi is newer than the C++ compiler, so generating more efficient code for the platform it's being run on.

To compare the speed of the two it would be interesting to strip all the VCL stuff out of both programs, leaving both with purely processing instructions (which should make them pretty identical code-wise) that we know exactly what is happening. Then, compile with compilers (both Borland if possible) that were available around the same date using the same kind of optimisations etc. That way you're comparing the generated code rather than the compilers themselves.

Just my thoughts on the subject - I'm no expert on benchmarking. Hope that helps a bit though.

Jim
 
Thanks mate, it at least gives me some sort of avenue to explore with it, i was literally clueless a few hours ago :D
 
Back
Top Bottom