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

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

Страницы: 1 2 3 4 5 6 7 Следующая »
#75
8:41, 29 июня 2009
strtest.dpr.90: result:=(result xor n) - n; //result - (n shl 1) * result;
0040AB96 0FB6D0           movzx edx,al
0040AB99 33F2             xor esi,edx
0040AB9B 2BF2             sub esi,edx

а вот по-моему

strtest.dpr.91: result:=result - (n shl 1) * result;
0040AB96 0FB6C0           movzx eax,al
0040AB99 03C0             add eax,eax
0040AB9B F7EE             imul esi
0040AB9D 2BF0             sub esi,eax


#76
8:45, 29 июня 2009

Sergio666

movzx edx,al
подозреваю, что ты скопировал только result:=(result xor n) - n; а n осталась байтом (а должна быть знаковым типом, чтоб получить целочисленное значение -1 т.е. 0xFFFFFFFF)
#77
8:50, 29 июня 2009

doc.
>>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);
Может лучше так

result2:=result*10+ord(s^)-48;
if result2<result then exit(nDef);
result:=result2;
#78
8:55, 29 июня 2009

murder
> Может лучше так
А зачем? Пугает длина строки? :)
Пугаться не надо там проверка сперва быстро, а уж потом точно. Если вылезаний  за диапазоны не будет то будут выполняться только первые три проверки. Так что получается тоже самое, по сути, но больше на одну переменную и одно ветвление.(Правка: вернее if , or скорей всего тоже ветвление)

Правка 2: да, result2<result может не сработать, ведь умножение то на 10 т.е. значение может перепрыгнуть через отрицательное значение и снова стать положительным.

Правка 3: чтоб было понятно: 0x20000000*10 = 0x01 04000000 , как видим рузультат после умножения будет положительным, однако переполнение было.

Правка 4: Надо еще учесть ассиметрию диапазона положительных/отрицательных чисел.

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-n))))) then exit(nDef);
  result:=result*10 + (ord(s^)-48);   // без скобок косяк с переполнением 
  inc(s);
 end;

 result:=(result xor n)-n;
end;

#79
10:05, 29 июня 2009

Sergio666
> Лучше использовать
> function _time:Extended;
> var C, F : Int64;
> begin
> QueryPerformanceCounter(C);
> QueryPerformanceFrequency(F);
> result:=C / F;
> end;
> Вместо GetTickCount
Изначально так и было, тока результат такой же был, а на GetTickCount перешел чтоб проверить, не накосячил ли где. Видимо делфи както оптимизирует код, а как тогда добиться истинности тестирования?
Народ покажите пожалуйста как Вы тестите функции.

#80
10:35, 29 июня 2009

louken
> а как тогда добиться истинности тестирования?
Делать несколько тестов одной ф-ции, и брать среднее значение. Потому что результаты измерений все-равно будут отличаться (в зависимости от фазы луны, времени суток и пр.)

#81
12:42, 29 июня 2009

Преобразование 64-битного целого без знака в систему счисления с основаниями от 2 до 16

procedure Convert_Num(x: int64; s: PChar; base: dword);assembler;stdcall;
const
  Convert_Digs: array[0..15] of char='0123456789ABCDEF';
asm
        push    ebp
        pushad
        xor     ebx,ebx
        mov     eax,dword[x]
        mov     edx,dword[x+4]
        mov     edi,[s]
        mov     ecx,[base]
        sub     esp,4
        mov     ebp,esp
        cld
        mov     esi,edi
        push    esi
//--- loop for each digit
        sub     bh,bh
        mov     [ebp],eax                //save low word
        mov     [ebp+4],edx              //save high word
        sub     esi,esi                  //count digits
@Connum1:
        inc     esi
        mov     eax,[ebp+4]              //high word of value
        sub     edx,edx                  //clear for divide
        div     ecx                      //divide, DX gets remainder
        mov     [ebp+4],eax              //save quotient (new high word)
        mov     eax,[ebp]                //low word of value
        div     ecx                      //divide, DX gets remainder
                                         //(the digit)
        mov     [ebp],eax                //save quotient (new low word)
        mov     bl,dl
        mov     al,byte[Convert_Digs+ebx]//get the digit
        stosb                            //store
        cmp     dword[ebp],0             //check if low word zero
        jne     @Connum1                 //jump if not
        cmp     dword[ebp+4],0           //check if high word zero
        jne     @Connum1                 //jump if not
        sub     al,al
        stosb                            //store the terminator
//--- reverse digits
        pop     ecx                      //restore start of string
        xchg    ecx,esi
        shr     ecx,1                    //number of reverses
        jz      @Connum3                 //jump if none
        xchg    edi,esi
        sub     esi,2                    //point to last digit
@Connum2 :
        mov     al,[edi]                 //load front character
        xchg    al,[esi]                 //swap with end character
        stosb                            //store new front character
        dec     esi                      //back up
        loop   @Connum2                  //loop back for each digit
//--- finished
@Connum3  :
        add     esp,4
        popad
        pop     ebp
end;
Оригинал тут

#82
13:10, 29 июня 2009

Sergio666
> Делать несколько тестов одной ф-ции, и брать среднее значение. Потому что
> результаты измерений все-равно будут отличаться (в зависимости от фазы луны,
> времени суток и пр.)
Это то понятно, я про то, что две абсолютно одинаковые (отличаются только именем) функции показывают разный результат тестирования - 655 и 715 мс (это и есть их среднее значение). Таким образом и сравнение двух разных функций может быть не корректно.

#83
13:57, 29 июня 2009

Причем, если поменять местами имена у функций то и результат меняется местами (т.е. есть привязка к конкретной функции). Такое ощущение что делфи сортирует функции по имени и при этом 2ая функция выполняется чуть медленнее. Если наклепать 6 одинаковых (или больше) функций с именами Func1, Func2, Func3,...,Func6 то результат выполнения функций чередуется и повторяется, т.е. для Func1=715; Func1=650; Func3=715; Func4=650; Func5=715; Func6=650; это конечно приблизительно, но сколько не запускай тест, цифры примерно такими и остаются. Прямо мистика какая-то.

Вот специально сравнил asm код функций, он также полностью идентичен, за исключением адресов естественно. Дак в чем же дело, может это всякие низкоуровневые штучки виноваты, типа кеш промах и др. Тока как быть тогда в таких ситуациях?

#84
14:23, 29 июня 2009

Извращенцы... зайдите на фасткод что ли, там наверняка лучше реализация чем у вас.

#85
14:24, 29 июня 2009

murder
> Преобразование 64-битного целого без знака в систему счисления с основаниями от 2 до 16
Зачем тут asm?

drv47
> Извращенцы... зайдите на фасткод что ли, там наверняка лучше реализация чем у вас.
Еще один :) Кто-то кроссворды отгадывает, а кто-то развлекается таким образом...

>зайдите на фасткод что ли
Для интереса заглянул, там такая хрень...

#86
14:37, 29 июня 2009

doc.
Хрень? Думаю их реализация сильно быстрее вашей ))
http://fastcode.sourceforge.net/challenge_content/StrToInt32.html

#87
14:38, 29 июня 2009

drv47
> Хрень? Думаю их реализация сильно быстрее вашей ))
ты туда заглядывал?

#88
14:51, 29 июня 2009

doc.
Куда? В СтрТоИнт нет, ибо на мой взгляд его оптимизировать нафиг не нужно. А вот их FastMove с успехом использую у себя.
Кстати их меморименаджером начиная с бдс 2006 официально заменили старый дельфишный.

#89
14:55, 29 июня 2009

drv47
> В СтрТоИнт нет
тогда и говорить не о чем.

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

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