Войти
ПрограммированиеФорумОбщее

Delphi 2009 - Оптимизация вашего приложения. (5 стр)

Страницы: 1 2 3 4 5 6 7 Следующая »
#60
19:30, 28 июня 2009

Новый вариант

function strtointSimple(s: PChar): integer;assembler;register;
asm
  push esi
  mov  esi,eax
  cmp  byte[esi],'0'
  sbb  edx,edx
  sub  esi,edx
  xor  ecx,ecx
  xor  eax,eax
  @1:mov   cl,[esi]
     lea   eax,[eax*4+eax]
     inc   esi
     lea   eax,[eax*2+ecx-48]
     cmp byte[esi],0
  jne @1
  xor  eax,edx
  sub  eax,edx
  pop  esi
end;
Плюс не понимает


#61
20:26, 28 июня 2009

murder
Вобщем если отключить у меня проверку на "+", то твой прирост скорости составит : 1 .1862319572019783991117391743212

#62
22:45, 28 июня 2009

С проверкой на адекватность и "+".

function StrToIntDef_Sergio666(s:PAnsiChar; nDef:integer = 0):integer;
var n : Byte;
begin
 n:=ord(s[0] = '-');
 inc(s, 1 + n + ord(s[0] = '+'));

 result:=ord(s[-1]) - 48;
 while s[0] <> #0 do begin
  if (ord(s[0]) < $30) or (ord(s[0]) > $39) then exit(nDef);
  result:=result * 10 + ord(s[0]) - 48;
  inc(s);
 end;

 result:=result - (n shl 1) * result;
end;
#63
22:51, 28 июня 2009

Sergio666
> С проверкой на адекватность и "+".
Осталасть только проверка переполнения ;)

>result:=result - 2*n*result;
>result:=result - (n shl 1) * result;
Плохой конструкт - сокращает диапазон в два раза.

Правка: небольшая подсказка :)
Обратить знак лучше так:  res = (res xor 0xFFFFFFFF) - 0xFFFFFFFF

Правка 2:
>result:=ord(s[-1]) - 48;
опс, нет проверки...

#64
0:10, 29 июня 2009

А стандартный StrToInt еще и пробелы в начале строки игнорирует

#65
0:12, 29 июня 2009

main
> StrToInt - это не та функция, которую стоит так уж оптимизировать
Это мы оптимизируем для разминки :)

PS: у меня ОЧЕНЬ много используется FloatToStrDef

#66
0:14, 29 июня 2009

doc.
> Осталасть только проверка переполнения ;)
экспоненту еще нужно до кучи, вот тогда можно сравнивать

#67
0:15, 29 июня 2009

louken
> экспоненту еще нужно до кучи, вот тогда можно сравнивать
Ну не обязательно. Ведь если ты знаешь, что у тебя не может попастся вот такой строки "  +174E+2", то смысл удалять пробелы и обрабатывать "E"?

#68
0:35, 29 июня 2009

>то смысл удалять пробелы и обрабатывать "E"?
чём точнее задача, тем легче решать.

#69
0:54, 29 июня 2009

Sergio666
> Ну не обязательно. Ведь если ты знаешь, что у тебя не может попастся вот такой
> строки " +174E+2", то смысл удалять пробелы и обрабатывать "E"?
Согласен, но в таком случае, какие бы то нибыло сравнения со стандартной StrToInt не имеют право на существование.

#70
1:04, 29 июня 2009

Народ подскажите, вот код, типа юнит-тест:

function StrToIntDef_Sergio666(s:PAnsiChar; nDef:integer = 0):integer;
var n : Byte;
begin
 n:=ord(s[0] = '-');
 inc(s, 1 + n + ord(s[0] = '+'));

 result:=ord(s[-1]) - 48;
 while s[0] <> #0 do begin
  if (ord(s[0]) < $30) or (ord(s[0]) > $39) then exit(nDef);
  result:=result * 10 + ord(s[0]) - 48;
  inc(s);
 end;

 result:=result - (n shl 1) * result;
end;

function StrToIntDef_Sergio666_New(s:PAnsiChar; nDef:integer = 0):integer;
var n : Byte;
begin
 n:=ord(s[0] = '-');
 inc(s, 1 + n + ord(s[0] = '+'));

 result:=ord(s[-1]) - 48;
 while s[0] <> #0 do begin
  if (ord(s[0]) < $30) or (ord(s[0]) > $39) then exit(nDef);
  result:=result * 10 + ord(s[0]) - 48;
  inc(s);
 end;

 result:=result - (n shl 1) * result;
end;

const
  CountIteration = 10000000;
  ConvertString = '+123456789';

type
  TFunc = function(s:PAnsiChar; nDef:integer = 0): integer;

function Calculate(Func: TFunc): string;
var i: Integer;
    k1, k2: Cardinal;
begin
  k1 := GetTickCount;
  for i := 1 to CountIteration do
    Func(ConvertString);
  k2 := GetTickCount;
  Result := IntToStr(k2 - k1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption := Calculate(StrToIntDef_Sergio666);
  Label2.Caption := Calculate(StrToIntDef_Sergio666_New);
end;
Этот код, поидее, должен сравнивать скорость работы двух функций StrToIntDef_Sergio666 и StrToIntDef_Sergio666_New. Сами функции полностью идентичные, тока название поменял. Хотел было сам попробовать поисправить код, замерить. При измерени скорости работы функций были получены разные результаты - ~710 и ~655 и примерно такие числа постоянно и получаются, сколько раз не выполняй измерения. Что я делаю не так, как правильно делать измерения?

#71
7:26, 29 июня 2009

Sergio666

function StrToIntDef_Sergio666(s:PChar; nDef:integer=0):integer;
var n : integer;
begin
 n:=-ord(s^='-');
 inc(s,ord(s^='+')-n);

 result:=0;
 while s^<>#0 do begin
  if (not (s^ in [#48,#49,#50,#51,#52,#53,#54,#55,#56,#57])) then exit(nDef);
  result:=result*10+ord(s^)-48;
  inc(s);
 end;

 result:=(result xor n)-n;
end;
#72
8:24, 29 июня 2009
function StrToIntDef_Sergio666(s:PChar; nDef:integer=0):integer;
var n : integer;
begin
 n:=-ord(s^='-');
 inc(s,ord(s^='+')-n);

 result:=0;
 while s^<>#0 do begin
  if (((result >= $0CCCCCCC)or(s^ < $30)or(s^ > $39))and((result > $0CCCCCCC)or(s^ < $30)or(s^ > $39)or((result = $0CCCCCCC)and(s^ > $37)))) then exit(nDef);
  result:=result*10+ord(s^)-48;
  inc(s);
 end;

 result:=(result xor n)-n;
end;
#73
8:30, 29 июня 2009

murder
> result:=(result xor n)-n;
Что-то с минусом не пашет...

louken
Лучше использовать

function _time:Extended;
var C, F : Int64;
begin
 QueryPerformanceCounter(C);
 QueryPerformanceFrequency(F);
 result:=C / F;
end;
Вместо GetTickCount
#74
8:35, 29 июня 2009

Sergio666
> Что-то с минусом не пашет...
а что генерит в asm?

Страницы: 1 2 3 4 5 6 7 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.