I wondered how much a performance difference you could get with the methods, so I dug about and checked. You are correct, the difference is huge. 1.17MS down to 0.0017MS per call. We really need some better thread synchronization techniques in Delphi!

I changed the timer style for greater accuracy as well, though it simply gave additional digits and no real great change except more significant digits. And processor usage with range from an average of 60% all the way up to 88% now for me. Also, the sleep command slows the processing by just a little.

That means that the 1,000,000 button only takes about 5 seconds. I'm uploading the final version now to replace the sample, and here is the final code for perusal. (So folks know my methods w/o downloading.)

[pascal]unit uMain;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;

type
TBenchmarkThread = class(TThread)
private
ExecutionTime: Cardinal;
constructor Create(Str: String; Count: Cardinal; ProgressBar: TProgressBar; CreateSuspended: boolean = false);
protected
fTimes: Cardinal; // The number of times we execute the same function.
fProg: TProgressBar; // Our Progressbar (multithreaded progressbar calls!).
fS: String;
procedure Execute; override;
end;
TForm1 = class(TForm)
Label1: TLabel;
resultLbl: TLabel;
progress: TProgressBar;
Button1: TButton;
Button2: TButton;
Button3: TButton;
QuitBtn: TButton;
procedure QuitBtnClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
private
working: boolean;
{ Private declarations }
procedure Benchmark(Times: Cardinal);
public
{ Public declarations }
end;

var
Form1: TForm1;
PerfFreq: Int64;

implementation

{$R *.dfm}

procedure TForm1.Benchmark(Times: Cardinal);
var t1,t2: TBenchmarkThread;
begin
working := true;
progress.Max := Times div 100;
progress.Position := 0;
resultLbl.Caption := '...';

t1 := TBenchMarkThread.Create( '10000', Times div 2, progress);
t2 := TBenchMarkThread.Create('-10000', Times div 2, progress);

while not t1.Terminated and not t2.Terminated do
Application.ProcessMessages;

// Calculate the average execution time:
resultLbl.Caption := floattostr((((t1.ExecutionTime + t2.ExecutionTime) / PerfFreq) / Times) * 1000)+' msec';

t1.Free;
t2.Free;
working := false;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if not working then
Benchmark(TButton(Sender).Tag);
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose := not working;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
QueryPerformanceFrequency(PerfFreq);
end;

procedure TForm1.QuitBtnClick(Sender: TObject);
begin
Close;
end;

{ TBenchmarkThread }

constructor TBenchmarkThread.Create(Str: String; Count: Cardinal; ProgressBar: TProgressBar; CreateSuspended: boolean = false);
begin
fS := Str;
fTimes := Count;
fProg := ProgressBar;

inherited Create(CreateSuspended);
end;

procedure TBenchmarkThread.Execute;
var i: cardinal;
q1,q2: Int64;
begin
for i := 1 to fTimes do begin
QueryPerformanceCounter(q1);
StrToInt(fS);
QueryPerformanceCounter(q2);
Inc(ExecutionTime,Abs(q2-q1));
if i mod 100 = 0 then Synchronize(fProg.StepIt); // This prevents simultaneous function calls. ESSENTIAL!
end;

Terminate; // Done, and prove it.
end;

end.[/pascal]