Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.12.09;
Скачать: CL | DM;

Вниз

Количество символов в DWORD-переменной   Найти похожие ветки 

 
Dib@zol ©   (2007-11-10 22:36) [0]

Здравствуйте, господа! Чёто припёрло меня сегодня - взялся затачивать IntToStr под PChar =))) И всё вроде хорошо, да вот бЯда - строка, если не знать длину записи числа в символах (сиречь байтах), идёт задом наперед. А если забивать её с конца, в начале могут образоваться ненужные лишние символы. В общем, у меня вопрос: как, не приводя ДВорд к строке, вычислить количество десятичных разрядов в нем? (Помню, была такая тема, но нигде - ни в хистори 1-го, ни 2-го бэкапов этого и в помине нет, а в архивах форума копаться - работка ещё та).

Если кому интересно, вот мой самопал :) Работает в 3.26 раз быстрее, чем стандартный IntToStr.
ЗЫ Знак для меня не важен, поэтому беззнаковостью DWORD"a попрекать не надо.

function IntToStr(D:DWORD):PChar;
asm
 PUSH EBX;
 PUSH ECX;
 PUSH EDX;
 PUSH EDI;

 MOV EBX, EAX;
 PUSH 11;       // length("4294967295"#0) = 11;
 CALL GetMemory;
 POP EDX;
 XOR EDX, EDX;
 XCHG EAX, EBX; // EBX - address of PChar, EAX - dividend
 MOV EDI, EBX;

 MOV ECX, 0Ah;  // 0Ah = 10 = divider

 @loop:
 IDIV ECX;
 ADD DL, 30h;   // 30h = 48 = ASCII-offset of the "0"
 MOV BYTE PTR [EBX], DL;
 XOR DL, DL;
 INC EBX;
 CMP EAX, 0;
 JNE @loop;

 MOV BYTE PTR [EBX], 0;
 MOV EAX, EDI;

 POP EDI;
 POP EDX;
 POP ECX;
 POP EBX;
end;


 
Zeqfreed ©   (2007-11-10 22:55) [1]

А не быстрее будет на стеке, например, выделить память под максимальное кол-во символов и после уже выделить память в куче и скопировать туда?


 
antonn ©   (2007-11-10 23:17) [2]

не понял, в чем загвоздка..
лишнее пообрубать, соусом полить и на стол:)
function Int2Str(const Value: Integer): string;
asm
      XOR       ECX, ECX
      PUSH      ECX
      ADD       ESP, -0Ch
      PUSH      EBX
      LEA       EBX, [ESP + 15 + 4]
      PUSH      EDX
      CMP       EAX, ECX
      PUSHFD
      JGE       @@1
      NEG       EAX
@@1:
      MOV       CL, 10
@@2:
      DEC       EBX
      CDQ
      IDIV      ECX
      ADD       DL, 30h
      MOV       [EBX], DL
      TEST      EAX, EAX
      JNZ       @@2
      POPFD
      JGE       @@3
      DEC       EBX
      MOV       byte ptr [EBX], "-"
@@3:
      POP       EAX
      MOV       EDX, EBX
      CALL      System.@LStrFromPChar
      POP       EBX
      ADD       ESP, 10h
end;


 
homm ©   (2007-11-11 00:14) [3]

Результаты тестов (mc):

                 IntToStr   Int2Str   Str  
D5 (DWORD)      | 1000     | 562     | 922 |
D5 (Integer)    | 625      | 516     | 500 |
D2007 (DWORD)   | 391      | 375     | 766 |
D2007 (Integer) | 296      | 359     | 328 |

Вариант из [0] отработал за 260мс и благополучно показал полную ахинею :)
Кака видим, Int2Str для DWORD самый шустрый, в D5, тормозит из-за @LStrFromPChar, в которой видимо память выделяется. Берем Int2Str, изменяем: выделяем память сами, копируем туда значение из стека и получаем еше быстрее.


 
antonn ©   (2007-11-11 01:07) [4]

просто IntToStr еще содержит код проверки самих данных и может ругаться мессаджбоксами, а Int2Str партизанит :)


 
Johnmen ©   (2007-11-11 01:23) [5]


> Dib@zol ©   (10.11.07 22:36) 

Изучай классиков жанра:
http://fastcode.sourceforge.net/



Страницы: 1 вся ветка

Текущий архив: 2007.12.09;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.022 c
2-1195214711
timekiller
2007-11-16 15:05
2007.12.09
Проверка на повторы по нодам


3-1185134768
Tendr
2007-07-23 00:06
2007.12.09
Соединение с СУБД Oracle через delphi


11-1180619713
=BuckLr=
2007-05-31 17:55
2007.12.09
Тип string в .Selection


15-1194273247
Ferra
2007-11-05 17:34
2007.12.09
Программирование в команде...


2-1194868661
cosy
2007-11-12 14:57
2007.12.09
найдите ошибку пожалуста уже 2 часа на этот сорц смотрю