суббота, 17 января 2015 г.

Как лучше брать поля объектных полей? Или Assigned() VS try-except.

Как лучше брать поля объектных полей? Что предпочесть - ясный и простой код с исключением в стиле Delphi, или проверки с повторным чтением объекта или использованием  промежуточных значений в стиле Pascal? Вот пример:

procedure TForm5.Button1Click(Sender: TObject);
var
  dt: TDateTime;
  I: Integer;
  A: array[ 0..9 ] of TStringList;
 
  function V: Integer;
  begin
    try
      Result := A[ I mod 10 ].Count;
    except
      Result := 0;
    end;
  end;
  function V2: Integer;
  var
    Index: Integer;
  begin
    Index := I mod 10;
    if Assigned( A[ Index ] ) then
      Result := A[ Index ].Count
    else
      Result := 0;
  end;
var
  Summ: Integer;
begin
  FillChar( A, SizeOf( A ), 0 );
  for I := Low(A) to High(A) do
  if Odd( I ) then
    A[I] := TStringList.Create;
 
  dt := Now;
  try
 
    Summ := 0;
    for I := 0 to 100000 do
    Summ := Summ + V;
 
    ShowMessage( IntToStr( Summ ) + ': ' + FormatDateTime( 'hh:nn:ss:zzz', Now-dt ) );
 
  finally
    for I := Low(A) to High(A) do
    if Odd( I ) then
      FreeAndNil( A[I] );
  end;
 
end;

Это событие нажатия на кнопку,  в результате работы которого у меня на экране компьютера появляется сообщение с такими цифрами: 0: 00:04:41:248(*). Т.е. около пяти минут на 100 тыс. записей. Много ли это? Скажу только, что изначально я ставил 1 миллион, и просто замучился ждать.

И вот, вместо Summ + V я ставлю Summ + V2, запускаю, жму кнопку... Оп! И 0: 00:00:00:002!


!!! Так вот как должен работать процессор с восемью ядрами на частоте 4 ГГц! И миллион операций ведёт к увеличению времени до 0.021 секунды. И 10 миллионов - лишь малая доля секунды...

Красивый, простой как 2 копейки код с try-exсept против жуть какого старого, извилистого, но всё ещё очень и очень доброго if... Если кто-то опять мне будет говорить, что новее - значит лучше, то скорее всего, я снова ему не поверю.

Кстати, надо погонять это дело на телефоне...

Примечание *: Такое ужасно время получено из-за запуска по F9 - с отладкой. Для такого рода замеров следует запускать Shift-Ctrl-F9, т.е. без отладки. Без отладки время ф-ии V будет уже 0,677 секунды, что ни в какое сравнение не идёт с 5-ю минутами. Однако, это всё же более, чем в 300 раз дольше варианта с V2. И к тому же совершенно очевидно, что отладка программы, где происходит исполнение такого рода кода, может стать весьма утомительным занятием. Спасибо Alexey Kazantsev за замечание по поводу отладчика.