[fpc-pascal] Efficient String concatenation

Antonio Fortuny a.fortuny at sitasoftware.lu
Thu Oct 31 13:18:52 CET 2013


Hi All.

Based upon the code into the post, I've driven a test case:
three platforms and Delphi 5, Delphi XE, Lazarus 1.0.12 (FPC 2.6.2)
For a comparison purpose, the main specific code has been written in a 
classical way, using implicit string and the optimized code uses the 
function result as explicit intermediate string.
All tests have been run the same way: the program has been reloaded for 
everyy run either classic or optimized
times shown are in minutes(always zero):seconds.ms
Two loops have been done: 10 meg loops and 100 meg.
There are the results:

Platform Vista 32
Delphi 5
10,000,000 iterations classic 00:05.735 - optimized 00:04.374
100,000,000 iterations classic 00:57.881 - optimized 00:44.386
Lazarus 1.0.12 Win32
10,000,000 iterations classic 00:02.487 - optimized 00:01.498
100,000,000 iterations classic 00:25.121 - optimized 00:16.528
Delphi XE on Vista32
10,000,000 iterations classic 00:01.757 - optimized 00:01.233
100,000,000 iterations classic 00:18.524 - optimized 00:13.204

Platform W7 x64 (virtual machine into Esxi4)
Delphi 5
10,000,000 iterations classic 00:05.491 - optimized 00:04.773
100,000,000 iterations classic 00:57.143 - optimized 00:49.780
Lazarus 1.0.12 Win32
10,000,000 iterations classic 00:03.213 - optimized 00:02.465
100,000,000 iterations classic 00:33.290 - optimized 00:25.21
Lazarus 1.0.12 Win64
10,000,000 iterations classic 00:03.962 - optimized 00:03.136
100,000,000 iterations classic 00:42.495 - optimized 00:34.523
Delphi XE w32
10,000,000 iterations classic 00:02.886 - optimized 00:02.153
100,000,000 iterations classic 00:31.013 - optimized 00:24.102

Platform Linux x64 (virtual machine into Esxi4)
Lazarus 1.0.12
10,000,000 iterations classic 00:03.348 - optimized 00:02.727
100,000,000 iterations classic 00:37.081 - optimized 00:28.810

Enjoy.

Antonio

-------------- next part --------------
object fMain: TfMain
  Left = 209
  Height = 337
  Top = 109
  Width = 376
  Caption = 'Concaténation de strings'
  ClientHeight = 337
  ClientWidth = 376
  LCLVersion = '1.0.12.0'
  object Panel1: TPanel
    Left = 0
    Height = 122
    Top = 0
    Width = 376
    Align = alTop
    ClientHeight = 122
    ClientWidth = 376
    TabOrder = 0
    object Label1: TLabel
      Left = 10
      Height = 14
      Top = 7
      Width = 48
      Caption = 'Itérations'
      ParentColor = False
    end
    object EIterations: TEdit
      Left = 60
      Height = 21
      Top = 4
      Width = 80
      TabOrder = 0
      Text = '100000'
    end
    object BtnClassique: TButton
      Left = 14
      Height = 25
      Top = 37
      Width = 75
      Caption = 'Classique'
      OnClick = BtnClassiqueClick
      TabOrder = 1
    end
    object BtnOptimise: TButton
      Left = 111
      Height = 25
      Top = 37
      Width = 75
      Caption = 'Optimisé'
      OnClick = BtnOptimiseClick
      TabOrder = 2
    end
    object BtnClose: TButton
      Left = 294
      Height = 25
      Top = 2
      Width = 75
      Caption = 'Fermer'
      OnClick = BtnCloseClick
      TabOrder = 3
    end
  end
  object Memo1: TMemo
    Left = 0
    Height = 215
    Top = 122
    Width = 376
    Align = alClient
    Lines.Strings = (
      'Memo1'
    )
    TabOrder = 1
  end
end
-------------- next part --------------
unit StrConcatMain;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;

type

  { TfMain }

  TfMain = class(TForm)
    Panel1: TPanel;
    Memo1: TMemo;
    Label1: TLabel;
    EIterations: TEdit;
    BtnClassique: TButton;
    BtnOptimise: TButton;
    BtnClose: TButton;
    procedure BtnClassiqueClick(Sender: TObject);
    procedure BtnOptimiseClick(Sender: TObject);
    procedure BtnCloseClick(Sender: TObject);
  private
    { private declarations }
    function Classique(const Iterations: Integer): String;
    function Optimise(const Iterations: Integer): String;
  public
    { public declarations }
  end;

var
  fMain: TfMain;

implementation

{$R *.lfm}

{ TfMain }

procedure TfMain.BtnClassiqueClick(Sender: TObject);
var
  Debut: TDateTime;
  Fin: TDateTime;
  Ecart: TDateTime;
  Iterations: Integer;
  Index: Integer;
begin
  Iterations := StrToIntDef(EIterations.Text, -1);
  if Iterations = -1 then begin
    MessageDlg('Erreur','Du numérique SVP', mtError, [mbOK], 0, mbOK);
    EIterations.SetFocus;
    Exit
  end;
  Debut := now;
  for Index := 0 to Iterations do
    Classique(Iterations);
  Fin := now;
  Ecart := Fin - Debut;
  Memo1.Lines.Add(Format('%d itérations en mode classique en %s', [Iterations, FormatDateTime('nn:ss.zzz', Ecart)]));
end;

procedure TfMain.BtnOptimiseClick(Sender: TObject);
var
  Debut: TDateTime;
  Fin: TDateTime;
  Ecart: TDateTime;
  Iterations: Integer;
  Index: Integer;
begin
  Iterations := StrToIntDef(EIterations.Text, -1);
  if Iterations = -1 then begin
    MessageDlg('Erreur','Du numérique SVP', mtError, [mbOK], 0, mbOK);
    EIterations.SetFocus;
    Exit
  end;
  Debut := now;
  for Index := 0 to Iterations do
    Optimise(Iterations);
  Fin := now;
  Ecart := Fin - Debut;
  Memo1.Lines.Add(Format('%d itérations en mode optimisé en %s', [Iterations, FormatDateTime('nn:ss.zzz', Ecart)]));
end;

function TfMain.Classique(const Iterations: Integer): String;
begin
  Result := IntToStr(Iterations) + ' constante';
end;

function TfMain.Optimise(const Iterations: Integer): String;
begin
  Result := IntToStr(Iterations);
  Result := Result + ' constante';
end;

procedure TfMain.BtnCloseClick(Sender: TObject);
begin
  Close
end;

end.



More information about the fpc-pascal mailing list