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
Sergio666
movzx edx,al
подозреваю, что ты скопировал только result:=(result xor n) - n; а n осталась байтом (а должна быть знаковым типом, чтоб получить целочисленное значение -1 т.е. 0xFFFFFFFF)
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;
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;
Sergio666
> Лучше использовать
> function _time:Extended;
> var C, F : Int64;
> begin
> QueryPerformanceCounter(C);
> QueryPerformanceFrequency(F);
> result:=C / F;
> end;
> Вместо GetTickCount
Изначально так и было, тока результат такой же был, а на GetTickCount перешел чтоб проверить, не накосячил ли где. Видимо делфи както оптимизирует код, а как тогда добиться истинности тестирования?
Народ покажите пожалуйста как Вы тестите функции.
louken
> а как тогда добиться истинности тестирования?
Делать несколько тестов одной ф-ции, и брать среднее значение. Потому что результаты измерений все-равно будут отличаться (в зависимости от фазы луны, времени суток и пр.)
Преобразование 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;Оригинал тут
Sergio666
> Делать несколько тестов одной ф-ции, и брать среднее значение. Потому что
> результаты измерений все-равно будут отличаться (в зависимости от фазы луны,
> времени суток и пр.)
Это то понятно, я про то, что две абсолютно одинаковые (отличаются только именем) функции показывают разный результат тестирования - 655 и 715 мс (это и есть их среднее значение). Таким образом и сравнение двух разных функций может быть не корректно.
Причем, если поменять местами имена у функций то и результат меняется местами (т.е. есть привязка к конкретной функции). Такое ощущение что делфи сортирует функции по имени и при этом 2ая функция выполняется чуть медленнее. Если наклепать 6 одинаковых (или больше) функций с именами Func1, Func2, Func3,...,Func6 то результат выполнения функций чередуется и повторяется, т.е. для Func1=715; Func1=650; Func3=715; Func4=650; Func5=715; Func6=650; это конечно приблизительно, но сколько не запускай тест, цифры примерно такими и остаются. Прямо мистика какая-то.
Вот специально сравнил asm код функций, он также полностью идентичен, за исключением адресов естественно. Дак в чем же дело, может это всякие низкоуровневые штучки виноваты, типа кеш промах и др. Тока как быть тогда в таких ситуациях?
Извращенцы... зайдите на фасткод что ли, там наверняка лучше реализация чем у вас.
murder
> Преобразование 64-битного целого без знака в систему счисления с основаниями от 2 до 16
Зачем тут asm?
drv47
> Извращенцы... зайдите на фасткод что ли, там наверняка лучше реализация чем у вас.
Еще один :) Кто-то кроссворды отгадывает, а кто-то развлекается таким образом...
>зайдите на фасткод что ли
Для интереса заглянул, там такая хрень...
doc.
Хрень? Думаю их реализация сильно быстрее вашей ))
http://fastcode.sourceforge.net/challenge_content/StrToInt32.html
drv47
> Хрень? Думаю их реализация сильно быстрее вашей ))
ты туда заглядывал?
doc.
Куда? В СтрТоИнт нет, ибо на мой взгляд его оптимизировать нафиг не нужно. А вот их FastMove с успехом использую у себя.
Кстати их меморименаджером начиная с бдс 2006 официально заменили старый дельфишный.
drv47
> В СтрТоИнт нет
тогда и говорить не о чем.
Тема в архиве.