Сейчас на форуме: jinoweb (+6 невидимых)

 eXeL@B —› Программирование —› ByteToHex
<< . 1 . 2 . 3 . 4 . 5 .
Посл.ответ Сообщение


Ранг: 756.3 (! !), 113thx
Активность: 0.610.05
Статус: Участник
Student

Создано: 07 июля 2018 22:06 · Поправил: Isaev
· Личное сообщение · #1

Не подскажите максимально быстрый способ перевода? Помню во времена доса на асме буквально из десятка байт был финт для этого дела, может помнит кто?
А то дельфовый IntToHex(n, 2) сожрал всю скорость, посмотрев сырки стало сразу понятно куда)

А вообще нужно из md5 массива байт строку собрать
если делать влоб
Code:
  1. s:='';
  2. for i:=0 to 15 do
  3.   s:=s+IntToHex(Digest[i], 2);

то 10млн раз выполняются около 6 сек, хотелось бы поделить это время на 2 или 3... к слову, если вместо IntToHex просто добавлять '00', то будет 2 сек. Пробовал вместо простой конкатенации заюзать TStringBuilder, но нынче, похоже менеджер памяти уже сам вполне справляется с этим хламом и с ним только на 1 сек дольше получается. Так же пробовал выделить память сразу под всю строку и мувами загонять на места, но получается тоже дольше... в общем проблема только в переводе в hex, остальное, похоже достаточно оптимально работает

-----
z+Dw7uLu5+jqLCDq7vLu8PvpIPHs7uMh




Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 06 августа 2018 11:23 · Поправил: dosprog
· Личное сообщение · #2

) А я-то думаю, чо оно так тормозит



Ранг: 15.8 (новичок), 3thx
Активность: 0.030.01
Статус: Участник

Создано: 07 августа 2018 11:43 · Поправил: bizkitlimp
· Личное сообщение · #3

Таблица вариант:
Code:
  1. var
  2.   HexTable : array [Word] of Byte;
  3.  
  4. procedure InitHexTable;
  5. var
  6. : Integer;
  7. : Integer;
  8. : Byte;
  9. : Byte;
  10. begin
  11. FillChar(HexTable, Length(HexTable), 0);
  12. for I := 0 to 255 do
  13.   for J := 0 to 255 do
  14.     case I of
  15.     $30..$39, $41..$46, $61..$66:
  16.       case J of
  17.       $30..$39, $41..$46, $61..$66:
  18.         begin
  19.           case I of
  20.           $41..$46: L := I - $30 - $7;
  21.           $61..$66: L := I - $50 - $7;
  22.           else      L := I - $30;
  23.           end;
  24.           case J of
  25.           $41..$46: H := J - $30 - $7;
  26.           $61..$66: H := J - $50 - $7;
  27.           else      H := J - $30;
  28.           end;
  29.           HexTable[(shl 8) or J] := (shl 4) or L;
  30.         end;
  31.       end;
  32.     end;
  33. end;
  34.  
  35. initialization
  36. InitHexTable;


Сами конверторы:
Code:
  1. function HexToInt64(const Src: PAnsiChar; const Len: Integer; out Value: Int64): Boolean;
  2. asm
  3.   test      rcx,rcx
  4.   jz        @@exit
  5.   test      edx,edx
  6.   jle       @@exit
  7.   cmp       edx,16
  8.   jg        @@exit
  9.   xor       r9d,r9d
  10.   mov       r11d,edx
  11.   shr       r11d,1
  12.   jz        @@byone
  13.   lea       r10,[HexTable]
  14.  
  15. @@bytwo:
  16.   movzx     eax,word ptr [rcx]
  17.   cmp       eax,$3030
  18.   movzx     eax,byte ptr [r10+rax]
  19.   jz        @@shift
  20.   test      al,al
  21.   jz        @@exit
  22.  
  23. @@shift:
  24.   shl       r9,8
  25.   or        r9,rax
  26.   add       rcx,2
  27.   sub       r11d,1
  28.   jnz       @@bytwo
  29.   test      edx,1
  30.   jz        @@valid
  31.  
  32. @@byone:
  33.   movzx     eax,byte ptr [rcx]
  34.   sub       eax,$30
  35.   cmp       eax,$09
  36.   jbe       @@final
  37.   sub       eax,$11
  38.   cmp       eax,$05
  39.   jbe       @@hex
  40.   sub       eax,$20
  41.   cmp       eax,$05
  42.   ja        @@exit
  43.  
  44. @@hex:
  45.   add       eax,$A
  46.  
  47. @@final:
  48.   shl       r9,4
  49.   or        r9,rax
  50.   
  51. @@valid:
  52.   mov       [r8],r9
  53.   mov       al,1
  54.   ret
  55.  
  56. @@exit:
  57.   xor       al,al
  58. end;
  59.  
  60. function HexToInt64(const Src: PWideChar; const Len: Integer; out Value: Int64): Boolean;
  61. asm
  62.   test      rcx,rcx
  63.   jz        @@exit
  64.   test      edx,edx
  65.   jle       @@exit
  66.   cmp       edx,16
  67.   jg        @@exit
  68.   xor       r9d,r9d
  69.   mov       r11d,edx
  70.   shr       r11d,1
  71.   jz        @@byone
  72.   lea       r10,[HexTable]
  73.  
  74. @@bytwo:
  75.   mov       eax,[rcx]
  76.   test      eax,$FF00FF00
  77.   jnz       @@exit
  78.   shl       ax,8
  79.   shr       eax,8
  80.   cmp       eax,$3030
  81.   movzx     eax,byte ptr [r10+rax]
  82.   jz        @@shift
  83.   test      al,al
  84.   jz        @@exit
  85.  
  86. @@shift:
  87.   shl       r9,8
  88.   or        r9,rax
  89.   add       rcx,4
  90.   sub       r11d,1
  91.   jnz       @@bytwo
  92.   test      edx,1
  93.   jz        @@valid
  94.  
  95. @@byone:
  96.   movzx     eax,word ptr [rcx]
  97.   sub       eax,$30
  98.   cmp       eax,$09
  99.   jbe       @@final
  100.   sub       eax,$11
  101.   cmp       eax,$05
  102.   jbe       @@hex
  103.   sub       eax,$20
  104.   cmp       eax,$05
  105.   ja        @@exit
  106.  
  107. @@hex:
  108.   add       eax,$A
  109.  
  110. @@final:
  111.   shl       r9,4
  112.   or        r9,rax
  113.   
  114. @@valid:
  115.   mov       [r8],r9
  116.   mov       al,1
  117.   ret
  118.  
  119. @@exit:
  120.   xor       al,al
  121. end;
Надо было обычную на 256.



Ранг: 173.8 (ветеран), 208thx
Активность: 0.120.36
Статус: Участник

Создано: 09 августа 2018 15:21 · Поправил: VOLKOFF
· Личное сообщение · #4

Новая задачка "нано-оптимизации" для Инде
Вернуть количество знаков числа. Навскидку сделал так:

Code:
  1. mov rax, [int64]
  2. mov rbx, 10
  3. xor rcx, rcx
  4. @@: 
  5. cqo
  6. idiv rbx
  7. inc rcx
  8. test rax, rax
  9. jne @B
  10. mov rax, rcx
  11. ret


Деление не быстрая штука, мб ускорить умножением, или просто запилить портянку сравнений с возвратами? Я чот после тренировки туго соображаю...




Ранг: 271.4 (наставник), 331thx
Активность: 0.321.49
Статус: Участник

Создано: 09 августа 2018 15:33 · Поправил: f13nd
· Личное сообщение · #5

VOLKOFF пишет:
Деление не быстрая штука, мб ускорить умножением

Сделай портянку из 19 сравнений, чубайс и инде нанооптимизацию оценят. И главное прокрутка будет без лагов.

-----
2 оттенка серого


| Сообщение посчитали полезным: VOLKOFF

Ранг: 15.8 (новичок), 3thx
Активность: 0.030.01
Статус: Участник

Создано: 09 августа 2018 17:46
· Личное сообщение · #6

Кол-во цифр:
Code:
  1. function NumDigits(const Value: Int64): Integer;
  2. asm
  3.   test      rcx,rcx
  4.   jz        @@zero
  5.   cvtsi2sd  xmm0,rcx
  6.   movq      rax,xmm0
  7.   mov       rcx,$7FFFFFFFFFFFFFFF
  8.   and       rax,rcx
  9.   shr       rax,52
  10.   sub       eax,$03FF
  11.   imul      eax,eax,19728
  12.   shr       eax,16
  13.   add       eax,1
  14.   ret
  15.  
  16. @@zero:
  17.   xor       eax,eax
  18. end;
Боялся округление 9999...-подобных таки не позволит, но вроде всё норм.



Ранг: 173.8 (ветеран), 208thx
Активность: 0.120.36
Статус: Участник

Создано: 09 августа 2018 19:05 · Поправил: VOLKOFF
· Личное сообщение · #7

bizkitlimp
оно конечно даже чуть быстрее прямого сравнения, но только выхлоп не тот

Code:
  1. +----------------------+-------+
  2. |                Val         | Result |
  3. +-------------------------------+
  4. |                  1          |   1   |
  5. |                 11         |   1   |
  6. |                111        |   2   |
  7. |               1111       |   4   |
  8. |              11111      |   4   |
  9. |             111111     |   5   |
  10. |            1111111    |   7   |
  11. |           11111111   |   7   |
  12. |          111111111  |   8   |
  13. |         1111111111 |  10   |
  14. +----------------------+-------+

итд

(парсер почему-то съел отступы)

| Сообщение посчитали полезным: bizkitlimp

Ранг: 15.8 (новичок), 3thx
Активность: 0.030.01
Статус: Участник

Создано: 09 августа 2018 20:18 · Поправил: bizkitlimp
· Личное сообщение · #8

Черт..
В оригинале:
Code:
  1. const
  2. MAX : Double = 1e18;
  3. ...
  4.   shr       rbx,52
  5.   sub       ebx,$03FF
  6.   imul      ebx,ebx,19728
  7.   shr       ebx,16
  8.   add       ebx,1
  9.   mov       edx,18
  10.   sub       edx,ebx
  11.   call      Power10
  12.   ucomisd   xmm0,[MAX] //if less than 1e18 then OK
  13.   jb        .continue
  14.   sub       ebx,1
  15. ...
Т.е. умножается входящее число на такое 1e??, чтоб оно стало X.XXXe17. Просто вытащить экспоненту из флоат-числа, хотя может и невозможно на самом деле. Придется побруткодить.

EDIT
log10 походу только, а это много кода. Распилить на две ветки через cmp rcx,10000000000 (10 миллиардов) - станет 9 или 10 сравнений. Нормально будет.


<< . 1 . 2 . 3 . 4 . 5 .
 eXeL@B —› Программирование —› ByteToHex
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати