Добавить комментарий

Delphi

Глобальные переменные vs Локальные

Меряем скорость чтения и записи. Переставляем местами значения двух переменных через третью. Каждый цикл - три чтения и три записи. Повторим 2 миллиарда раз. 

Проверяем глобальные переменные, локальные, локальные, но не наши, а уровнем выше и атрибуты класса.

Код теста:

program SpeedTest;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.Classes,
  System.SysUtils,
  System.Diagnostics;

const
  cTestSize = 2000000000;

type
  TSpeedTest = class
                 Fi,Fj,Fk : integer;

                 Function LocalVariable: integer;
                 Function ClassVariable: integer;
                 Function SubLocalVariable: integer;
                 Function GlobalVariable: integer;
               end;

var
  t : TStopwatch;
  Gk, Gi, Gj : integer;

{ TSpeedTest }

function TSpeedTest.ClassVariable: integer;
var
    i: integer;
    t: TStopwatch;
begin
  t := TStopwatch.StartNew;
  for I := 0 to cTestSize do
  begin
    Fk := Fi;
    Fi := Fj;
    Fj := Fk;
  end;
  t.Stop;
  result := t.ElapsedMilliseconds;
end;

function TSpeedTest.GlobalVariable: integer;
var
    i: integer;
    t: TStopwatch;
begin
  t := TStopwatch.StartNew;
  for I := 0 to cTestSize do
  begin
    Gk := Gi;
    Gi := Gj;
    Gj := Gk;
  end;
  t.Stop;
  result := t.ElapsedMilliseconds;
end;

function TSpeedTest.LocalVariable: integer;
var
    i,j,k,ii: integer;
    t: TStopwatch;
begin
  t := TStopwatch.StartNew;
  for ii := 0 to cTestSize do
  begin
    k := i;
    i := j;
    j := k;
  end;
  t.Stop;
  result := t.ElapsedMilliseconds;
end;

function TSpeedTest.SubLocalVariable: integer;
var
    i,j,k: integer;

    function SubTest: integer;
    var ii : integer;
        t  : TStopwatch;
    begin
      t := TStopwatch.StartNew;
      for ii := 0 to cTestSize do
      begin
        k := i;
        i := j;
        j := k;
      end;
      t.Stop;
      result := t.ElapsedMilliseconds;
    end;

begin
  result := SubTest;
end;

var
    SpeedTest: TSpeedTest;

begin
  try
    SpeedTest := TSpeedTest.Create;
    try
      WriteLn('Global  : ', FormatFloat('0.000', SpeedTest.GlobalVariable / 1000));
      WriteLn('Local   : ', FormatFloat('0.000', SpeedTest.LocalVariable / 1000));
      WriteLn('SubLocal: ', FormatFloat('0.000', SpeedTest.SubLocalVariable / 1000));
      WriteLn('Class   : ', FormatFloat('0.000', SpeedTest.ClassVariable / 1000));
    finally
      SpeedTest.Free;
    end;
  except
    on e: exception do
      writeln(e.Message);
  end;
  writeln('I''m finished.');
  readln;
end.

Получаем результат:

Global  : 6.525
Local   : 6.506
SubLocal: 6.542
Class   : 7.065
I'm finished.

Вывод:

  Глобальная переменная или локальная из стека - на быстродействии это никак не сказывается. Медленнее происходит только работа с атрибутами класса. Потери составляют 7-9%.

Тестировалось на Delphi 10.1

Метки:

Filtered HTML

  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Допустимые HTML-теги: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Строки и абзацы переносятся автоматически.
  • Вы можете цитировать другие сообщения, используя тэг [quote]

Plain text

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Строки и абзацы переносятся автоматически.